我创建了两个视图控制器。我从第一个到第二个创建了一个segue来传递数据。现在我想将数据从第二个视图控制器传递到第一个视图控制器。我经历了许多类似的问题而我无法实现这些问题,因为我缺乏有关如何解开的知识。
ViewController.swift
class ViewController: UIViewController
{
var dataRecieved: String?
@IBOutlet weak var labelOne: UILabel!
@IBAction func buttonOne(sender: UIButton)
{
performSegueWithIdentifier("viewNext", sender: self)
}
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!)
{
var svc: viewControllerB = segue.destinationViewController as! viewControllerB
svc.dataPassed = labelOne.text
}
}
这会将数据传递给视图控制器" viewControllerB"中的dataPassed。说,现在我想将一些数据从viewControllerB传递到ViewController中的dataRecieved。如何只使用unwind segue而不是使用委托来完成此操作。我对swift很新,会很感激详细解释。
答案 0 :(得分:60)
ØyvindHauge打败了我同样的解决方案方法,但由于我已经开始提供更详细的答案,我也会添加它。
假设您的两个视图控制器命名如下:
ViewController
(vcA)
ViewControllerB
(vcB)
您可以像在示例中那样设置(vcA) -> (vcB)
中的segue
/* in ViewController.swift */
// ...
// segue ViewController -> ViewControllerB
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!)
{
if segue.identifier == "viewNext" {
let viewControllerB = segue.destinationViewController as! ViewControllerB
viewControllerB.dataPassed = labelOne.text
}
}
接下来有点棘手的步骤是,使用此方法,用于将数据从 (vcB)
传递回 (vcA)
的的segue是< em>还作为(vcA)
方法添加到@IBAction
的来源(而不是,可能会预期,添加到(vcB)
的来源)。
/* in ViewController.swift */
// ...
// segue ViewControllerB -> ViewController
@IBAction func unwindToThisView(sender: UIStoryboardSegue) {
if let sourceViewController = sender.sourceViewController as? ViewControllerB {
dataRecieved = sourceViewController.dataPassed
}
}
您之后通过(vcB)
中的手册(vcA)
segue将Exit
中的一个按钮与(vcB)
中的展开操作相关联:
下面是将文字从(vcA)
传递到(vcB)
的完整示例; (可能)通过UITextField
修改该文本,最后将(可能)修改后的文本返回(vcA)
。
(vcA)
来源:
/* ViewController.swift: Initial view controller */
import UIKit
class ViewController: UIViewController {
var dataRecieved: String? {
willSet {
labelOne.text = newValue
}
}
@IBOutlet weak var labelOne: UILabel!
@IBAction func buttonOne(sender: UIButton) {
performSegueWithIdentifier("viewNext", sender: self)
}
// set default labelOne text
override func viewDidLoad() {
super.viewDidLoad()
labelOne.text = "Default passed data"
}
// segue ViewController -> ViewControllerB
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!)
{
if segue.identifier == "viewNext" {
let viewControllerB = segue.destinationViewController as! ViewControllerB
viewControllerB.dataPassed = labelOne.text
}
}
// segue ViewControllerB -> ViewController
@IBAction func unwindToThisView(sender: UIStoryboardSegue) {
if let sourceViewController = sender.sourceViewController as? ViewControllerB {
dataRecieved = sourceViewController.dataPassed
}
}
}
(vcB)
来源(请注意,此处UITextFieldDelegate
委托仅用于“本地”变更dataPassed
属性的值,该属性将返回(vcA)
并且分配给后者的dataRecieved
属性
/* ViewControllerB.swift */
import UIKit
class ViewControllerB: UIViewController, UITextFieldDelegate {
var dataPassed : String?
@IBOutlet weak var textField: UITextField!
// set default textField text to the data passed from previous view.
override func viewDidLoad() {
super.viewDidLoad()
textField.text = dataPassed
// Handle the user input in the text field through delegate callbacks
textField.delegate = self
}
// UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
// User finished typing (hit return): hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(textField: UITextField) {
dataPassed = textField.text
}
}
执行示例:
答案 1 :(得分:11)
我就是这样做的:
在视图控制器1中创建一个插座,如下所示:
@IBAction func unwindToViewController1(segue: UIStoryboardSegue) {
let foo = segue.sourceViewController.foo
// TODO: Use foo in view controller 1
}
连接视图控制器2(您正在展开的vc),如下所示。从vc2中的黄色圆圈拖到&#39;退出&#39;。应该弹出视图控制器1的IBAction。选择它。
现在,每当您从视图控制器2中展开时,视图控制器1中的unwindToViewController1:
方法都会被调用。
这是您从视图控制器2检索所需属性的位置。请注意,您需要将segue.sourceViewController
强制转换为自定义视图控制器子类才能获得正确的属性。
答案 2 :(得分:1)
如果您的应用支持iOS 9+,您可以传递与prepareForSegue几乎相同的数据,请使用UIStoryboardUnwindSegueSource属性的sender,该属性与sender
属性完全相同prepare(for segue: UIStoryboardSegue, sender: Any?)
如何使用它:
注意:连接unwindTo方法与@ØyvindHauge和@dfri在答案中解释相同。
fromViewController
是否是您来自的类型sender
属性强制转换为您发送的类型并返回true 代码片段(Swift 4.0):
@IBAction func unwindToMyFirstViewController(segue: UIStoryboardSegue) {}
override func canPerformUnwindSegueAction(_ action: Selector, from fromViewController: UIViewController, withSender sender: Any) -> Bool {
if fromViewController is MyCustomViewController,
let customType = sender as? MyCustomType {
return true
}
return false
}