简体   繁体   English

协议委托未按预期传递数据 [Swift5]

[英]Protocol Delegate not passing data as expected [Swift5]

I have created simple Protocol Delegate to pass data from One View Controller to Second View Controller - but data seems to be not carried across?我创建了简单的协议委托,将数据从 One View Controller 传递到 Second View Controller - 但数据似乎没有传递?

Details: First View Controller have a textField where I type my data (String) to be passed to Second VC.详细信息:第一个视图 Controller 有一个文本字段,我在其中键入要传递给第二个 VC 的数据(字符串)。 I also have a button with Action to trigger transition to Second View Controller.我还有一个带有 Action 的按钮来触发转换到 Second View Controller。 Second View Controller comes up but data from First View Controller does not show up - expected behaviour was for the Label in Second VC to be updated with my data from First VC.第二个视图 Controller 出现,但来自第一个视图 Controller 的数据没有显示 - 预期的行为是第二个 VC 中的 Label 将使用我来自第一个 VC 的数据进行更新。 I also have created a segue from Button on FVC to SVC with the identifier ' sendDataIdentifier '.我还使用标识符“ sendDataIdentifier ”创建了从 FVC 上的 Button 到 SVC 的 segue。

What I'm doing wrong?我做错了什么?

Code and screenshots below:代码和截图如下:

First View Controller第一视角 Controller

import UIKit

protocol SendDataDelegte {
    func sendData(data: String)
}

class FirstViewController: UIViewController {

    var delegate: SendDataDelegte? = nil

    @IBOutlet weak var dataCaptured: UITextField!

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

    @IBAction func sendDataButton(_ sender: Any) {
        let dataToBeSent = self.dataCaptured.text
        self.delegate?.sendData(data: dataToBeSent!)
    }
}

Second View Controller第二视图 Controller

import UIKit

class SecondViewController: UIViewController, SendDataDelegte {

    @IBOutlet weak var dataRetrived: UILabel!
    @IBAction func closeButton(_ sender: Any) {
         dismiss(animated: true, completion: nil)
    }

    func sendData(data: String) {
        self.dataRetrived.text = data
    }

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

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "sendDataIdentifier" {
            let firstVC: FirstViewController = segue.destination as! FirstViewController
            firstVC.delegate = self
        }
    }
}

在此处输入图像描述

You have it the wrong way around.你搞错了。

You don't need a delegate pattern in this instance.在这种情况下,您不需要委托模式。 You need to implement prepare(for segue) in the first view controller and just pass the data to the destination view controller.您需要在第一个视图 controller 中实现prepare(for segue)并将数据传递到目标视图 controller。

prepare(for segue) isn't called in the destination view controller and the delegate property will be nil in the first view controller because nothing is setting it.在目标视图 controller 中未调用prepare(for segue) ,并且在第一个视图 controller 中delegate属性将为nil ,因为没有设置它。

class FirstViewController: UIViewController {

    @IBOutlet weak var dataCaptured: UITextField!

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

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let dest = segue.destination as? SecondViewController {
            dest.text = self.dataCaptured.text
        }
    }
}

class SecondViewController: UIViewController {

    @IBOutlet weak var dataRetrived: UILabel!
    var text: String?
    @IBAction func closeButton(_ sender: Any) {
         dismiss(animated: true, completion: nil)
    }

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

    override func viewWillAppear(_ animated:Bool) {
        super.viewWillAppear(animated)
        self.dataRetrieved.text = text
    }
}

To push data forward, you can use present method要向前推送数据,您可以使用present方法

And to send data backward use delegate.并使用委托向后发送数据。

Example:例子:

First Screen第一个屏幕

import UIKit

protocol SendDataDelegte: class {
    func sendData(data: String)
}


class FirstViewController: UIViewController, SendDataDelegte {
    
    var dataCaptured: UITextField = {
        let txt = UITextField()
        txt.translatesAutoresizingMaskIntoConstraints = false
        txt.backgroundColor = .lightGray
        return txt
    }()
    
    var sendDataButton: UIButton = {
        let btn = UIButton()
        btn.translatesAutoresizingMaskIntoConstraints = false
        btn.backgroundColor = .lightGray
        return btn
    }()

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

    @objc func sendDataButtonAction() {
        let dataToBeSent = self.dataCaptured.text
        let vc = SecondViewController()
        vc.delegate = self
        vc.getDataLabel.text = dataToBeSent
        vc.modalPresentationStyle = .popover
        present(vc, animated: true, completion: nil)
    }
    
    func sendData(data: String) {
        sendDataButton.setTitle(data, for: .normal)
    }
    
    func setupUI() {
        view.backgroundColor = .blue
        view.addSubview(dataCaptured)
        dataCaptured.widthAnchor.constraint(equalToConstant: 200).isActive = true
        dataCaptured.heightAnchor.constraint(equalToConstant: 100).isActive = true
        dataCaptured.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        dataCaptured.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        
        view.addSubview(sendDataButton)
        sendDataButton.setTitle("Send Data", for: .normal)
        sendDataButton.titleColor(for: .normal)
        sendDataButton.widthAnchor.constraint(equalToConstant: 200).isActive = true
        sendDataButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
        sendDataButton.topAnchor.constraint(equalTo: dataCaptured.bottomAnchor, constant: 50).isActive = true
        sendDataButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        
        sendDataButton.addTarget(self, action: #selector(sendDataButtonAction), for: .touchUpInside)
    }
}

Second Screen第二屏

import UIKit

class SecondViewController: UIViewController {
    
    weak var delegate: SendDataDelegte?
    
    var getDataLabel: UILabel = {
        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        return lbl
    }()

    var dataCaptured: UITextField = {
        let txt = UITextField()
        txt.translatesAutoresizingMaskIntoConstraints = false
        txt.backgroundColor = .lightGray
        return txt
    }()
    
    var sendDataButton: UIButton = {
        let btn = UIButton()
        btn.translatesAutoresizingMaskIntoConstraints = false
        btn.backgroundColor = .lightGray
        return btn
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupUI()
    }
    
    @objc func sendDataButtonAction() {
        let string = dataCaptured.text!
        delegate?.sendData(data: string)
        dismiss(animated: true, completion: nil)
    }
    
    func setupUI() {
        view.backgroundColor = .yellow
    
        view.addSubview(getDataLabel)
        getDataLabel.backgroundColor = .lightGray
        getDataLabel.widthAnchor.constraint(equalToConstant: 200).isActive = true
        getDataLabel.heightAnchor.constraint(equalToConstant: 50).isActive = true
        getDataLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
        getDataLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
 
        view.addSubview(dataCaptured)
        dataCaptured.widthAnchor.constraint(equalToConstant: 200).isActive = true
        dataCaptured.heightAnchor.constraint(equalToConstant: 100).isActive = true
        dataCaptured.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        dataCaptured.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        
        view.addSubview(sendDataButton)
        sendDataButton.setTitle("Send Data", for: .normal)
        sendDataButton.titleColor(for: .normal)
        sendDataButton.widthAnchor.constraint(equalToConstant: 100).isActive = true
        sendDataButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
        sendDataButton.topAnchor.constraint(equalTo: dataCaptured.bottomAnchor, constant: 50).isActive = true
        sendDataButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        
        sendDataButton.addTarget(self, action: #selector(sendDataButtonAction), for: .touchUpInside)
    }
    

}

When we call present method on first screen, we send data to second screen's label and assign delegate to self.当我们在第一个屏幕上调用present方法时,我们将数据发送到第二个屏幕的 label 并将委托分配给自己。

When we tap button on second screen, we call delegate method and send text to button title on first screen.当我们在第二个屏幕上点击按钮时,我们调用委托方法并将文本发送到第一个屏幕上的按钮标题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM