[英]Passing data from UITableViewDataSource to UIViewController using protocol and delegate in Swift
[英]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.