如何实现两个ViewController之间的委托在swift中使用segue?

How to achieve delegation between two ViewController use segue in swift?

我对 swift 中的委派有点困惑。比如说,如果我想将 BViewController 中的文本字段文本传递给 AViewController。 (AViewController 有一个标签,但我没有放任何文本,所以它什么也没有显示)在用户完成输入并单击 "LETS GO" 按钮后,AViewController 中标签的文本应该显示相同的文本。我实现了代码,但它给了我一些错误。谢谢

代码:

import UIKit

class AViewController: UIViewController, BViewDelegate {


    @IBOutlet weak var labelTextData: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()


    }

    func userDoneInput(textData: String) {
        labelTextData.text = textData
    }



}




import UIKit

protocol BViewDelegate{
    func userDoneInput(textData: String)
}

class BViewController: UIViewController {


    @IBOutlet weak var UserInputText: UITextField!
    var bViewDelegate: BViewDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()


    }


    @IBAction func LetsGo(_ sender: UIButton) {
       self.performSegue(withIdentifier: "ShowData", sender: self)

    }

    //use segue
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier  == "ShowData" {
            let destination = segue.destination as! AViewController
            destination.labelTextData.text = UserInputText.text

        }
    }

}

1-A显示

2- 当你对 B 执行 segue 时在此处设置委托(此代码在 A 内)

@IBAction func MoveToB (_ sender: UIButton) {
   self.performSegue(withIdentifier: "GoToB", sender: self)

}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier  == "GoToB" {
        let destination = segue.destination as! BViewController
        destination.bViewDelegate = self
    }
}

3-当你想return从B到A时(这段代码在B里面)

self.bViewDelegate?.userDoneInput(textData: UserInputText.text!)
self.dismiss(animated:true,completion:nil)

4- 从 B 到 A 不应该有任何 segue

首先,最好不要使用 return 从 A 到 B 的 segue(事实上,您根本不是 returning,而是将 A 的新实例放在上面B).有多种选择。这是三个:

  • 使用展开转场。
  • 如果您以模态方式呈现 B,则调用 B 的 dismiss 函数(您的图像表明这是您正在做的,但代码中缺少它)。
  • 如果您将 B 显示为导航控制器的一部分,则调用 B 的 navigationController 的 popViewController(animated:) 方法。

在您从 A 介绍 B 之前,您需要将 B 的委托 属性 设置为 A(您目前没有这样做)。 然后你出示B。 然后,当用户在 B 上点击 "LET'S GO" 时,只需调用 self.dismiss(或替代方案 - 请参阅上面的选项),同时调用 self.delegate.userDoneInput(textData:).

很简单:

界面生成器设置

A 有一个您可以在 B 中编辑的标签。有两个按钮可以让您来回导航。重要的是,您不要按住 Ctrl 并单击 "Go back to A" 按钮以转到 A。这样做会在您的层次结构中添加另一个控制器:A 呈现 B,呈现 另一个 A .相反,B应该解散自己以显示原来的A(见下面的代码)。

代码

//
// AViewController.swift
//
class AViewController: UIViewController {
    @IBOutlet weak var label: UILabel!

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "gotoB", let bController = segue.destination as? BViewController {
            // Give B a chance to finish loading before using its outlets
            bController.loadViewIfNeeded()
            bController.textField.text = label.text
            bController.delegate = self
        }
    }
}

extension AViewController: BViewControllerDelegate {
    // B says that it has ended. We now update the label in A
    func bViewControllerDidEnd(_ controller: BViewController, textValue: String) {
        label.text = textValue
    }
}

//
// BViewController.swift
//
protocol BViewControllerDelegate {
    // For delegate methods, it's customary to pass in the object that triggers this delegate
    // (the BViewController), in case you need to make use of its other properties
    func bViewControllerDidEnd(_ controller: BViewController, textValue: String)
}

class BViewController: UIViewController {
    @IBOutlet weak var textField: UITextField!
    var delegate: BViewControllerDelegate?

    @IBAction func goBackToA(_ sender: Any) {
        // Tell the delegate that "I'm done"
        delegate?.bViewControllerDidEnd(self, textValue: textField.text!)

        // Dismiss B, not segue to another instance of A
        self.dismiss(animated: true)
    }
}