2016-12-09 62 views
0

我一直试着让这个工作,但无济于事。我正在尝试从SendingVC传递数组到一个ReceivingVC,并在两个标签中显示该数组的内容。使用协议/代理传递数组

SendingVC代码:

import UIKit 

protocol SenderVCDelegate { 
    func passArrayData(data: [String]) 
} 

class SendingVC: UIViewController { 

    // DELEGATE 
    var delegate: SenderVCDelegate? 

    var carDetails: [String]? = ["BMW", "X5"] 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

    @IBAction func unwindToFirst(segue: UIStoryboardSegue) { 
     // 
    } 

    override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { 
     if (carDetails?.isEmpty)! { 
      return false 
     } else { 
      if let delegate = delegate, let data = carDetails { 
       delegate.passArrayData(data: data) 
       print("from inside segue: \(data)") 
      } 

      return true 
     } 
    } 
} 

ReceivingVC代码

import UIKit 

class ReceivingVC: UIViewController, SenderVCDelegate { 
    @IBOutlet weak var lbl01: UILabel! 
    @IBOutlet weak var lbl02: UILabel! 

    var incomingCarDetails: [String] = [] 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     print("from inside viewLoad: \(incomingCarDetails)") 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

    override func prepare(for segue: UIStoryboardSegue, sender: Any?){ 
     if let sendingVC: SendingVC = segue.destination as? SendingVC { 
      sendingVC.delegate = self 
     } 
    } 

    func passArrayData(data: [String]) { 
     incomingCarDetails = data 

     populateLabels(array: incomingCarDetails) 
    } 

    func populateLabels(array: [String]) { 
     for (index, value) in array.enumerated() { 
      switch index { 
      case 0: 
       lbl01.text = value 
      case 1: 
       lbl02.text = value 
      default: 
       break 
      } 
     } 
    } 
} 

任何帮助,将不胜感激! :)

谢谢!

+1

你不需要这个委托。您只需将属性设置为'preparaForSegue' – Paulw11

+0

谢谢,但我想为此使用委托。 – halkibsi

+1

好的,你仍然需要在'prepareForSegue'中设置委托,但它确实没有意义。你将在'ReceivingVC'的实例上设置一个属性,使它能够调用'SendingVC'上的函数来获得从'SendingVC'返回的数组;为什么不在'ReceivingVC'上设置数组属性并完成? – Paulw11

回答

1

您似乎对代理的角色以及应该实施的位置感到困惑。您不需要使用代理将数据从SendingVC传递到RecevingVC,您可以简单地将目标视图控制器上的属性设置为prepareForSegue;

class SendingVC: UIViewController { 

    func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     if let destVC = segue.destinationViewController as? ReceivingVC { 
      destVC.incomingCarDetails = self.carDetails 
     } 
    } 
} 

如果要使用委托,那么你将在prepareForSegue设置SendingVC实例作为ReceivingVC的代表,改变你的协议,委托方法返回的数据,而不是接受数据:

protocol SenderVCDelegate { 
    func passArrayData() -> [String] 
} 

然后,你可以实现的委托方法和设置委托在prepareForSegue

class SendingVC: UIViewController, SenderVCDelegate { 

    func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     if let destVC = segue.destinationViewController as? ReceivingVC { 
      destVC.senderDelegate = self 
     } 
    } 

    func passArrayData() -> [String] { 
     return self.carDetails 
    } 
} 

ReceivingVC可以调用委托方法在viewWillAppear

class ReceivingVC: UIViewController { 

    var incomingCarDetails = [String]() 
    var senderDelegate: SenderVCDelegate? 

    override func viewWillAppear(animated: bool) { 
     super.viewWillAppear(animated) 

     if let incomingDetails = self.senderDelegate?.passArrayData() { 
      self.incomingCarDetails = incomingDetails 
     } 
    } 
} 

正如你可以看到这是一个整体大量的工作,并没有任何好处。通常在您想要发送数据的地方使用委托模式,并且其中函数调用将在不可预知的时间发生,例如响应网络操作完成或用户交互。

+0

非常感谢! – halkibsi