繁体   English   中英

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

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

我创建了简单的协议委托,将数据从 One View Controller 传递到 Second View Controller - 但数据似乎没有传递?

详细信息:第一个视图 Controller 有一个文本字段,我在其中键入要传递给第二个 VC 的数据(字符串)。 我还有一个带有 Action 的按钮来触发转换到 Second View Controller。 第二个视图 Controller 出现,但来自第一个视图 Controller 的数据没有显示 - 预期的行为是第二个 VC 中的 Label 将使用我来自第一个 VC 的数据进行更新。 我还使用标识符“ sendDataIdentifier ”创建了从 FVC 上的 Button 到 SVC 的 segue。

我做错了什么?

代码和截图如下:

第一视角 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!)
    }
}

第二视图 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
        }
    }
}

在此处输入图像描述

你搞错了。

在这种情况下,您不需要委托模式。 您需要在第一个视图 controller 中实现prepare(for segue)并将数据传递到目标视图 controller。

在目标视图 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
    }
}

要向前推送数据,您可以使用present方法

并使用委托向后发送数据。

例子:

第一个屏幕

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)
    }
}

第二屏

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)
    }
    

}

当我们在第一个屏幕上调用present方法时,我们将数据发送到第二个屏幕的 label 并将委托分配给自己。

当我们在第二个屏幕上点击按钮时,我们调用委托方法并将文本发送到第一个屏幕上的按钮标题。

暂无
暂无

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

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