Xcode Swift委托,VC实例化时新值将被覆盖

时间:2019-12-16 04:32:34

标签: ios swift xcode

我对授权迅速提出了一个小问题。我正在尝试将文本从ViewController发送到SecondViewController。加载第二个屏幕时,它仍然显示“ OLD TEXT”而不是“ NEW TEXT”,这是我的代码。发生的情况是,当视图控制器加载时,“ textReceived”变量的值再次被旧文本覆盖,不确定为什么这是我的代码:

protocol DataTransferTestProtocol {
    func receiveTextFromVC1(_ text: String)
}

class ViewController: UIViewController {

    var delegate: DataTransferTestProtocol?

    override func viewDidLoad() {
        super.viewDidLoad()

        let receivingVC = SecondViewController()
        self.delegate = receivingVC
    }

    @IBAction func buttonTapped(_ sender: Any) {
        delegate?.receiveTextFromVC1("NEW TEXT")
    }
}


class SecondViewController: UIViewController, DataTransferTestProtocol {

    @IBOutlet weak var myLabel: UILabel!

    var textReceived = "OLD TEXT"

    func receiveTextFromVC1(_ text: String) {
        textReceived = text
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        myLabel.text = textReceived
    }
}

5 个答案:

答案 0 :(得分:1)

问题是这一行:

    let receivingVC = SecondViewController()

您想与您可能在屏幕上看到的SecondViewController实例进行对话。但是,相反,您正在制作另一个 SecondViewController,您将永远不会在屏幕上看到。因此,发送给委托人的更改将永远不可见。 (您可能想阅读我关于http://www.programmingios.net/dont-make-a-new-instance-by-mistake/的文章。)

另一个问题是您是否应该在这里使用委托。委托通常是用于从第二视图控制器向第一视图控制器进行通讯。向前通信要简单得多:第一个视图控制器了解第二个视图控制器的全部知识,并直接与其进行通信。 (如果您要解释这些视图控制器是什么以及它们在全导入视图控制器层次结构中如何相互关联,我们可以对此进行更具体的说明。)

答案 1 :(得分:1)

如果要在导航中发送A->B。您应该使用属性而非委托。在您的情况下,当您将数据发送回上一个控制器A <-B时应该使用委托。
不要复杂的委托过程。

如果您要发送数据 firstVC-> secondVC ,请在secondVC中声明属性

  class secondVC: UIViewController {   
     pText : String?
  }

假设您基于某些操作将控制器推至secondVC

if let secondVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "secondVC") as? secondVC {

    secondVC.pText =  " " // string you want to pass.

    navigationController?.pushViewController(secondVC, animated: true)
} 

如果您要发送数据 firstVC <-secondVC ,请在secondVC中声明委托

protocol secondVCdelegate : class{
    func updateLable(text:String)
} 

class secondVC: UIViewController {   
     weak var delegate  : secondVCdelegate?
}

firstVC 中收到的委托人引用。

if let secondVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "secondVC") as? secondVC {

    secondVC.delegate =  self //.

    navigationController?.pushViewController(secondVC, animated: true)
} 

secondVC中声明firstVC协议

extension firstVC : secondVCdelegate{
    func updateLable(text:String){
      // update your label here
    }
}

希望这会有所帮助!

答案 2 :(得分:0)

因为您的let receivingVC = SecondViewController()中有viewDidLoad。当您退出该函数时,您的receivingVC实例也将被取消分配。相反,让您的receivingVC作为班级成员

class ViewController: UIViewController {

    var delegate: DataTransferTestProtocol?

    var receivingVC = SecondViewController() // have your receivingVC here

    override func viewDidLoad() {
        super.viewDidLoad()

        self.delegate = receivingVC
    }

    @IBAction func buttonTapped(_ sender: Any) {
        delegate?.receiveTextFromVC1("NEW TEXT")
    }
}

答案 3 :(得分:0)

非常简单的解决方案:

var receivingVC = SecondViewController()

只需将这一行从viewDidLoad()方法中移出

并像这样在该方法之上对其进行初始化。

class ViewController: UIViewController {
    let receivingVC = SecondViewController()

    var delegate: DataTransferTestProtocol?

override func viewDidLoad() {
    super.viewDidLoad()

    self.delegate = receivingVC
}

@IBAction func buttonTapped(_ sender: Any) {
    delegate?.receiveTextFromVC1("NEW TEXT")
}
}

答案 4 :(得分:0)

这是我基于响应的解决方案,必须获取正确的视图控制器:

@IBAction func buttonTapped(_ sender: Any) {

    let storyboard1 = UIStoryboard(name: "Main", bundle: nil)
    let secondVC = storyboard1.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
    self.delegate = secondVC      
    delegate?.receiveTextFromVC1("NEW TEXT")
    self.present(secondVC, animated: true, completion: nil)

}