如何实现两个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)
}
}
我对 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)
}
}