【问题标题】:Sending data with Segue with Swift使用 Swift 使用 Segue 发送数据
【发布时间】:2014-11-23 05:04:43
【问题描述】:

我有两个视图控制器和两个视图。 在我的第一个视图中,我将变量“currentUser”设置为 false。 我需要能够在第二个视图控制器中将 'currentUser' 设置为 true。

当尝试从第二个视图中引用“currentUser”时,它不会将其拾取,因为“currentUser”是在第一个视图控制器中定义的。

如何使用 segue 跨变量?

【问题讨论】:

    标签: ios swift segue


    【解决方案1】:

    使用 segues 将任何 ViewController 中的值设置为第二个

    像这样:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    
        if(segue.identifier == "yourIdentifierInStoryboard") {
    
            let yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass)
            yourNextViewController.value = yourValue
    

    在你的 NextViewController 类中。

    class yourNextViewControllerClass {
    
        var value:Int! // or whatever
    

    您也可以通过编程方式调用它:

     self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)
    

    将 DestinationViewController 中的值设置回主(第一个)ViewController

    1.实现一个协议,例如创建一个名为protocol.swift的文件。

        protocol changeUserValueDelegate {
           func changeUser(toValue:Bool)
        }
    

    2.在您的第二个视图上设置代理

        class yourNextViewControllerClass {
    
        var delegate:changeUserValueDelegate?
    

    3.设置代理加载(prepareForSegue)

        if(segue.identifier == "yourIdentifierInStoryboard") {
    
            var yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass)
            yourNextViewController.delegate = self
    

    4.向FirstViewController添加Function

        func changeUser(toValue:Bool) {
            self.currentUserValue = toValue
        }
    

    5.从您的 SecondViewController 调用此函数

         delegate?.changeUser(true)
    

    6. 在您的 FirstViewController 中设置委托

        class FirstViewController: UIViewController, ChangeUserValueDelegate {
    

    【讨论】:

    • 据我所知,我无法使用函数,我需要在“if”语句中执行此操作。抱歉没有说得更清楚。
    • 通过这两种方法,您可以将数据从第一个视图控制器发送到第二个视图控制器,并从第二个视图控制器发送回第一个。在“if”语句中调用它应该不是问题。
    • 我尝试了第一种方法,我无法在if语句中使用override函数,在第二个视图控制器中找不到变量。
    • 非常好的解决方案。在找到这个之前,我搜索了很多方法来返回到 firstViewController。一个附带的好处是我现在已经编写并使用了我的第一个本土协议!
    • 对理解这种控制器间协议通信变体的启示,谢谢。
    【解决方案2】:

    这里的问题是您的currentUser 变量是Bool 类型,这是一个值类型。因此,将它从您的第一个视图控制器传递到您的第二个视图控制器实际上会创建一个新的 Bool 实例。您需要将第一个视图控制器的引用传递给第二个视图控制器(有关 Swift 值和引用的更多详细信息,请参阅Value and Reference Types)。

    因此,根据您的需要/偏好,您可以选择以下三个示例之一。


    1。拳击风格

    在这里,我们将Bool“装箱”在一个类中,并将该类实例的引用传递给第二个视图控制器。

    1.1.创建一个CurrentUser 类:

    class CurrentUser {
        var someBooleanValue = true {
            didSet {
                print(someBooleanValue)
            }
        }
    }
    

    1.2.为第一个视图控制器创建一个UIViewController 子类:

    import UIKit
    
    class ViewController1: UIViewController {
    
        let currentUser = CurrentUser()
        
        override func viewDidLoad() {
            super.viewDidLoad()
            currentUser.someBooleanValue = false
        }
        
        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
            if let viewController2 = segue.destinationViewController as? ViewController2 {
                viewController2.currentUser = currentUser
            }
        }
    
    }
    

    1.3。为第二个视图控制器创建一个UIViewController 子类:

    import UIKit
    
    class ViewController2: UIViewController {
    
        var currentUser: CurrentUser?
    
        // Link this IBAction to a UIButton or a UIBarButtonItem in the Storyboard
        @IBAction func toggleBoolean(sender: AnyObject) {
            if let currentUser = currentUser {
              currentUser.someBooleanValue = !currentUser.someBooleanValue
            }
        }
        
    }
    

    2。闭包风格

    在这里,我们在闭包中获得第一个视图控制器的弱引用,并将这个闭包传递给第二个视图控制器。

    2.1.为第一个视图控制器创建一个UIViewController 子类:

    import UIKit
    
    class ViewController1: UIViewController {
        
        var currentUser = true {
            didSet {
                print(currentUser)
            }
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
            currentUser = false
        }
        
        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
            if let viewController2 = segue.destinationViewController as? ViewController2 {
                let closureToPerform = { [weak self] in
                    if let strongSelf = self {
                        strongSelf.currentUser = !strongSelf.currentUser
                    }
                }
                viewController2.closureToPerform = closureToPerform
            }
        }
        
    }
    

    2.2.为第二个视图控制器创建一个UIViewController 子类:

    import UIKit
    
    class ViewController2: UIViewController {
    
        var closureToPerform: (() -> Void)?
    
        // Link this IBAction to a UIButton or a UIBarButtonItem in the Storyboard
        @IBAction func toggleBoolean(sender: AnyObject) {
            closureToPerform?()
        }
        
    }
    

    3。协议委托风格

    在这里,我们使我们的第一个视图控制器符合某种协议,并将它的弱引用传递给第二个视图控制器。

    3.1.创建自定义协议:

    protocol MyDelegate: class {
        func changeValue()
    }
    

    3.2.为第一个视图控制器创建一个UIViewController 子类,并使其符合之前的协议:

    import UIKit
    
    class ViewController1: UIViewController, MyDelegate {
    
        var currentUser = true {
            didSet {
                print(currentUser)
            }
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
            currentUser = false
        }
        
        func changeValue() {
            currentUser = !currentUser
        }
        
        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
            if let viewController2 = segue.destinationViewController as? ViewController2 {
                viewController2.delegate = self
            }
        }
    
    }
    

    3.3.为第二个视图控制器创建一个UIViewController 子类:

    import UIKit
        
    class ViewController2: UIViewController {
    
        weak var delegate: MyDelegate?
    
        // Link this IBAction to a UIButton or a UIBarButtonItem in the Storyboard
        @IBAction func toggleBoolean(sender: AnyObject) {
            delegate?.changeValue()
        }
        
    }
    

    【讨论】:

      【解决方案3】:

      在目标视图控制器中添加属性currentUserSecondVC,并使用prepareForSegue

      override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
          if segue.identifier == "Name Of Your Segue" {
              var vc = segue.destinationViewController as NameOfTheSecondViewController
              vc.currentUserSecondVC = !currentUser //you can do whatever you want with it in the 2nd VC
          }
      }
      

      【讨论】:

        【解决方案4】:

        应该定义为override的函数是:

        open func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if (segue.identifier == "Segue Name Defined In Storyboard") {
                //set the property of the designated view controller with the value you need
            }
        }
        

        【讨论】:

          【解决方案5】:

          由于您在两个 Viewcontrollers 中使用相同的变量,即 currentUser(类型 Bool)。

          因此最好将其设为两个类中的全局变量。

          当谈到 swift 中的全局变量概念时。

          默认情况下,swift 中的所有内容都是公开的,因此如果您声明如下内容:

          class FirstViewController: UIViewController {
          
              var someVariable: Boll = YES
          
              init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
                  super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
              }
          }
          

          只要您有它的实例,您就可以访问它并设置值:

          var MySecondViewController: FirstViewController = FirstViewController(nibName: nil, bundle: nil)
          var getThatValue = MySecondViewController.someVariable
          

          【讨论】:

            猜你喜欢
            • 2019-09-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多