我创建了两个视图控制器。我创建了一个从第一个到第二个的段来传递数据。现在我想将数据从第二个视图控制器传递到第一个视图控制器。我经历了许多类似的问题,但我无法实现这些问题,因为我缺乏关于解开工作原理的知识。
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。比方说,现在我想在ViewController中从viewControllerB向dataRecieved传递一些数据。我如何才能只使用展开段而不使用委托来完成这项工作。我是swift的新手,希望您能给我详细的解释。
发布于 2016-02-10 20:04:26
solution比我先用了同样的解决方法,但由于我已经开始了更详细的答案,所以我也会添加它。
假设你的两个视图控制器命名如下:
ViewController
视图:ViewControllerB
您将按照示例中的操作从(vcA) -> (vcB)
设置段
/* 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)
的段也被添加到(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)
中的手动Exit
段将(vcB)
中的按钮连接到(vcA)
中的此展开操作
下面是一个将文本从(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
}
}
示例执行:
发布于 2016-02-10 19:32:04
这就是我要做的:
@IBAction func unwindToViewController1(segue: UIStoryboardSegue) { let foo = segue.sourceViewController.foo // TODO:在视图控制器1中使用foo }
unwindToViewController1:
方法都会被调用。segue.sourceViewController
强制转换为自定义视图控制器子类,以便获得正确的属性。发布于 2018-02-22 20:45:49
如果你的应用程序支持iOS 9+,你可以像prepareForSegue一样传递数据,使用具有sender属性的UIStoryboardUnwindSegueSource,该属性与sender
中的prepare(for segue: UIStoryboardSegue, sender: Any?)属性完全相同。
使用方法:
注意:连接unwindTo方法的与他们在答案中解释的@äyvind Hauge和@dfri相同。
在要展开到的视图控制器内,重写此方法的方法,检查类型fromViewController
是否为您从
sender
属性强制转换为您发送的类型,否则返回true
<>G222
代码片段(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
}
https://stackoverflow.com/questions/35313747
复制相似问题