如何解决协议委托未按预期传递数据 [Swift5]
我创建了简单的协议委托来将数据从一个视图控制器传递到第二个视图控制器 - 但数据似乎没有传递?
详情: 第一个视图控制器有一个文本字段,我在其中输入要传递给第二个 VC 的数据(字符串)。 我还有一个带有 Action 的按钮来触发到第二个视图控制器的转换。 第二个视图控制器出现,但第一个视图控制器的数据没有显示 - 预期的行为是第二个 VC 中的标签用我来自第一个 VC 的数据更新。 我还使用标识符“sendDataIdentifier”创建了从 FVC 上的 Button 到 SVC 的转场。
我做错了什么?
代码和截图如下:
第一个视图控制器
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!)
}
}
第二个视图控制器
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
}
}
}
解决方法
你的方法不对。
在这种情况下您不需要委托模式。您需要在第一个视图控制器中实现 prepare(for segue)
并将数据传递给目标视图控制器。
prepare(for segue)
不会在目标视图控制器中调用,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,for: .touchUpInside)
}
}
当我们在第一个屏幕上调用 present 方法时,我们将数据发送到第二个屏幕的标签并将委托分配给 self。
当我们在第二个屏幕上点击按钮时,我们调用委托方法并将文本发送到第一个屏幕上的按钮标题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。