协议委托未按预期传递数据 [Swift5]
Protocol Delegate not passing data as expected [Swift5]
我创建了简单的协议委托来将数据从一个视图控制器传递到第二个视图控制器 - 但数据似乎没有被传送?
详情:
第一个视图控制器有一个文本字段,我在其中键入要传递给第二个 VC 的数据(字符串)。
我还有一个带有 Action 的按钮,用于触发到 Second View Controller 的转换。
第二个视图控制器出现,但来自第一个视图控制器的数据未显示 - 预期的行为是第二个 VC 中的标签将使用第一个 VC 中的数据进行更新。
我还创建了一个从 FVC 上的 Button 到 SVC 的 segue,标识符为 'sendDataIdentifier'.
我做错了什么?
下面的代码和截图:
第一个视图控制器
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, constant: 50).isActive = true
sendDataButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
sendDataButton.addTarget(self, action: #selector(sendDataButtonAction), for: .touchUpInside)
}
}
当我们在第一个屏幕上调用 present 方法时,我们将数据发送到第二个屏幕的标签并将委托分配给自己。
当我们点击第二个屏幕上的按钮时,我们调用委托方法并将文本发送到第一个屏幕上的按钮标题。
我创建了简单的协议委托来将数据从一个视图控制器传递到第二个视图控制器 - 但数据似乎没有被传送?
详情: 第一个视图控制器有一个文本字段,我在其中键入要传递给第二个 VC 的数据(字符串)。 我还有一个带有 Action 的按钮,用于触发到 Second View Controller 的转换。 第二个视图控制器出现,但来自第一个视图控制器的数据未显示 - 预期的行为是第二个 VC 中的标签将使用第一个 VC 中的数据进行更新。 我还创建了一个从 FVC 上的 Button 到 SVC 的 segue,标识符为 'sendDataIdentifier'.
我做错了什么?
下面的代码和截图:
第一个视图控制器
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, constant: 50).isActive = true
sendDataButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
sendDataButton.addTarget(self, action: #selector(sendDataButtonAction), for: .touchUpInside)
}
}
当我们在第一个屏幕上调用 present 方法时,我们将数据发送到第二个屏幕的标签并将委托分配给自己。
当我们点击第二个屏幕上的按钮时,我们调用委托方法并将文本发送到第一个屏幕上的按钮标题。