首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用展开段传递数据

使用展开段传递数据
EN

Stack Overflow用户
提问于 2016-02-10 19:19:54
回答 3查看 20.9K关注 0票数 33

我创建了两个视图控制器。我创建了一个从第一个到第二个的段来传递数据。现在我想将数据从第二个视图控制器传递到第一个视图控制器。我经历了许多类似的问题,但我无法实现这些问题,因为我缺乏关于解开工作原理的知识。

ViewController.swift

代码语言:javascript
复制
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的新手,希望您能给我详细的解释。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-02-10 20:04:26

solution比我先用了同样的解决方法,但由于我已经开始了更详细的答案,所以我也会添加它。

假设你的两个视图控制器命名如下:

  • 主视图/入口点:ViewController 视图:ViewControllerB

您将按照示例中的操作从(vcA) -> (vcB)设置段

代码语言:javascript
复制
/* 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)的源代码中)。

代码语言:javascript
复制
/* 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)来源:

代码语言:javascript
复制
/* 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属性)

代码语言:javascript
复制
/* 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
    }
}

示例执行:

票数 65
EN

Stack Overflow用户

发布于 2016-02-10 19:32:04

这就是我要做的:

  1. 在视图控制器1中创建插座,如下所示:

@IBAction func unwindToViewController1(segue: UIStoryboardSegue) { let foo = segue.sourceViewController.foo // TODO:在视图控制器1中使用foo }

  • 连接视图控制器2(您正在展开的vc ),如下所示。从vc2中的黄色圆圈拖动到“退出”。来自视图控制器1的IBAction应该会弹出。选择它。

  1. 现在,每当您从视图控制器2展开时,视图控制器1中的unwindToViewController1:方法都会被调用。
  2. 这是您从视图控制器2检索所需属性的位置。请注意,您需要将segue.sourceViewController强制转换为自定义视图控制器子类,以便获得正确的属性。
票数 15
EN

Stack Overflow用户

发布于 2018-02-22 20:45:49

如果你的应用程序支持iOS 9+,你可以像prepareForSegue一样传递数据,使用具有sender属性的UIStoryboardUnwindSegueSource,该属性与sender中的prepare(for segue: UIStoryboardSegue, sender: Any?)属性完全相同。

使用方法:

  1. 创建一个unwindTo方法。

注意:连接unwindTo方法的与他们在答案中解释的@äyvind Hauge和@dfri相同。

在要展开到的视图控制器内,重写此方法的方法,检查类型fromViewController是否为您从

  • 获得的类型。如果是,请将sender属性强制转换为您发送的类型,否则返回true

  • ,返回false

<>G222

代码片段(Swift 4.0):

代码语言:javascript
复制
@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
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35313747

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档