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

如何在swift中使用segue实现两个ViewController之间的委派?,swift,segue,protocols,delegation,Swift,Segue,Protocols,Delegation,我对swift中的abt代表团有点困惑。比方说,如果我想将BViewController中textfield的文本传递给AViewController。(AViewController有一个标签,但我没有放任何文本,因此它在那里什么也没有显示)用户完成输入并单击“放手”按钮后,AViewController中的标签文本应显示相同的文本。我实现了代码,但它给了我一些错误。谢谢 代码: 1-A节目 2-执行segue to B时,在此处设置委托(此代码位于A中) 3-当您想从B返回A时(B中的代码)

我对swift中的abt代表团有点困惑。比方说,如果我想将BViewController中textfield的文本传递给AViewController。(AViewController有一个标签,但我没有放任何文本,因此它在那里什么也没有显示)用户完成输入并单击“放手”按钮后,AViewController中的标签文本应显示相同的文本。我实现了代码,但它给了我一些错误。谢谢

代码:

1-A节目

2-执行segue to B时,在此处设置委托(此代码位于A中)

3-当您想从B返回A时(B中的代码)


4-从B到A不应该有任何分段首先,最好不要使用分段从A返回到B(事实上,您根本没有返回,而是将A的新实例置于B之上)。有多种选择。以下是三点:

  • 使用一个放松段
  • 如果您以模态方式呈现B,则调用B的disclose函数(您的图像表明这就是您正在执行的操作,但代码中缺少它)
  • 如果将B显示为导航控制器的一部分,则调用B的navigationController的popViewController(动画:)方法
在从A显示B之前,您需要将B的委托属性设置为A(您目前没有这样做)。 那么你现在是B。 然后,当用户点击B上的“LET'S GO”时,只需调用self.disclose(或alternative-参见上面的选项),还可以调用self.delegate.userDoneInput(textData:)。

这非常简单:

界面生成器设置 A有一个标签,您可以在B中编辑。有两个按钮允许您来回导航。重要的是,不要按住Ctrl键并单击“返回A”按钮切换到A。这样做会将另一个控制器添加到您的层次结构中:A表示B,B表示另一个A。相反,B应自行关闭以显示原始A(请参见下面的代码)

代码
您创建了一个循环流。通常使用委托将数据从堆栈顶部的viewcontroller传递到堆栈下方的viewcontroller(A调用B,您希望将数据从B传递回A)。在您的示例中,您将再次堆叠(请记住,这是一个新实例),并使用prepare for segue向前传递数据。在您的示例中,您没有使用delegate.Sh_Khan THX,它可以正常工作,但我并不真正理解您的代码。为什么要使用self.bViewDelegate?.userDoneInput(textData:UserInputText.text!)?我可以用另一种方式构建segue吗,比如从B->A而不是A->B?就像你说self.AVController?.userDoneInput(textData:UserInputText.text!)一样,如果你从B->A中分离出来,这将导致循环流,在旧的oneSh_Khan的上方再次呈现A,我的意思是,我只保留一段B->A(不在乎A必须首先在应用程序中显示),它仍然有效吗?为什么我们需要一个代表团?或者我们只需要一个从视图控制器移动的序列?Sori,我有太多的问题,谢谢你不需要一个阶段来授权,你可以从a展示/推送B,想法是将B中的代表链接到a中的自我,从一个VC转移到另一个VC你需要一个阶段/展示/推送
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

        }
    }

}
@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
    }
}
self.bViewDelegate?.userDoneInput(textData: UserInputText.text!)
self.dismiss(animated:true,completion:nil)
//
// 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)
    }
}