快速从另一个访问 Viewcontroller 的实例

Posted

技术标签:

【中文标题】快速从另一个访问 Viewcontroller 的实例【英文标题】:Access the instance of a Viewcontroller from another in swift 【发布时间】:2014-08-08 13:06:18 【问题描述】:

我正在尝试将数据从一个视图控制器的文本字段传输到另一个视图控制器的标签。

如何从另一个视图控制器的代码中调用视图控制器实例?我正在使用情节提要,因此我从未在代码中创建视图控制器的实例?实例是自动创建的吗?他们叫什么名字?

感谢您的帮助!

【问题讨论】:

在 ViewController A 中,您创建 ViewController B。现在您可以访问 ViewController B,因此只需设置属性或向 ViewController B 发送消息。现在您可以将 ViewController B 推送到导航控制器上。 Passing data between View Controllers using Segue 的可能重复项 【参考方案1】:

1。如果包含文本字段的视图控制器可以调用(使用 segue)包含标签的视图控制器...

在您的项目中添加一个新的 Cocoa Touch 类文件,将其命名为 FirstViewController 并在其中设置以下代码:

import UIKit

class FirstViewController: UIViewController 
    
    @IBOutlet weak var textField: UITextField! // FIXME: link this to the UITextField in the Storyboard!!!
    
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
        let controller = segue.destinationViewController as! SecondViewController
        controller.text = textField.text
    
    

在您的项目中添加一个新的 Cocoa Touch 类文件,将其命名为 SecondViewController 并在其中设置以下代码:

import UIKit

class SecondViewController: UIViewController 
    
    var text: String?
    @IBOutlet weak var label: UILabel! // FIXME: link this to the UILabel in the Storyboard!!!
    
    override func viewDidLoad() 
        super.viewDidLoad()
        
        label.text = text
    
    

在 Storyboard 中,将第一个视图控制器嵌入到 UINavigationController 中。使用UIButtonUIBarButtonItem 将第一个视图控制器链接到第二个视图控制器。将第一个视图控制器的名称设置为FirstViewController,将第二个视图控制器的名称设置为SecondViewController。在第一个视图控制器中创建一个UITextField。在第二个视图控制器中创建一个UILabel。将文本字段和标签链接到它们各自在 FirstViewControllerSecondViewController 中的声明。


2。如果包含标签的视图控制器可以调用(使用 segue)包含文本字段的视图控制器...

在这里,这是一个完美的协议/委托案例。你可能会在 *** 上找到很多处理这个的东西。但是,这是一个粗略的例子。

在您的项目中添加一个新的 Cocoa Touch 类文件,将其命名为 FirstViewController 并在其中设置以下代码:

import UIKit

class FirstViewController: UIViewController, DetailsDelegate 
    
    @IBOutlet weak var label: UILabel! // FIXME: link this to the UILabel in the Storyboard
    
    func updateLabel(withString string: String?) 
        label.text = string
    
    
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
        let controller = segue.destinationViewController as! SecondViewController
        controller.delegate = self
    
    

在您的项目中添加一个新的 Cocoa/Cocoa Touch 类文件,将其命名为SecondViewController 并在其中设置以下代码:

import UIKit

protocol DetailsDelegate: class 
    func updateLabel(withString string: String?)


class SecondViewController: UIViewController 
    
    weak var delegate: DetailsDelegate?
    @IBOutlet weak var textField: UITextField! // FIXME: link this to the UITextField in the Storyboard
    
    override func viewWillDisappear(animated: Bool) 
        super.viewWillDisappear(animated)
        
        delegate?.updateLabel(withString: textField.text)
    


在 Storyboard 中,将第一个视图控制器嵌入到 UINavigationController 中。使用UIButtonUIBarButtonItem 将第一个视图控制器链接到第二个视图控制器。将第一个视图控制器的名称设置为FirstViewController,将第二个视图控制器的名称设置为SecondViewController。在第一个视图控制器中创建一个UILabel。在第二个视图控制器中创建一个UITextField。将文本字段和标签链接到它们各自在 FirstViewControllerSecondViewController 中的声明。

【讨论】:

有没有办法在没有 segue 的情况下实现这样的目标? 嗨。我有着同样的问题。但就我而言,我没有使用故事板。我正在使用xib。那么如何在不使用 segue 的情况下将委托引用从第一个视图控制器发送到第二个视图控制器?【参考方案2】:

Imanou Petit 和 Oscar Swanros 已经正确回答。然而,有一个替代方案相当“hacky”,我不得不使用它在 2 个视图控制器之间传输数据,而无需连接它们。

要获取应用的根视图控制器,您可以:

UIApplication.sharedApplication().windows[0].rootViewController

从那里你可以得到任何你想要的视图控制器。例如,如果您想要根视图控制器的第二个子视图控制器,那么您可以这样做:

let viewController = UIApplication.sharedApplication().windows[0].rootViewController?.childViewControllers[1] as? YourViewController
viewController?.yourProperty = newValue

请记住,这种方法相当“hacky”,可能违反了最佳编码实践。

【讨论】:

有一个正确回答的问题,为什么要提供一些可能违反最佳编码实践的“hacky”?【参考方案3】:

你需要在视图控制器之间创建一个 Segue:

    在情节提要上,选择ViewController A。 按住Control的同时,单击ViewController A,将蓝线拖放到ViewController B。如果ViewController A 嵌入在NavigationController 中,请从松开时出现的菜单中选择“显示”。否则,选择“模态呈现”。 在 Storyboard 上选择 Segue,然后在实用程序面板上,转到 Attributes Inspector 并为您的 segue 分配一个标识符(例如:“DetailSegue”)。

现在,当你想在ViewController A 上触发 segue 时,你只需要调用(可能是点击一个按钮):

@IBAction func buttonTapped() 
    self.performSegueWithIdentifier("DetailSegue", sender: self)

要将值传递给ViewController B,请覆盖ViewController A 上的prepareForSegue:sender 方法:

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) 
    if segue.identifier == "DetailSegue" 
        var viewControllerB = segue.destinationViewController as ViewControllerB
        viewControllerB.text = self.textField.text
    

非常简单。

请注意,要使其正常工作,您的 ViewController B 类应如下所示:

class ViewControllerB: UIViewController 
    ver label = UILabel(...)
    var text: String? 

    override func viewDidLoad() 
        super.viewDidLoad()

        label.text = text!
    

希望这会有所帮助。

【讨论】:

我们如何使用 Swift 在 FirstViewController 中创建 SecondViewController 的属性实例 谢谢!我被困在如何在情节提要中制作 segue 而没有 viewController1 中的按钮来附加它

以上是关于快速从另一个访问 Viewcontroller 的实例的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中从另一个 ViewController 访问变量

从另一个类访问 viewController 元素

如何从另一个 viewController 访问 tabBar 单击

从另一个被关闭的 vc 访问 viewcontroller 时的运行方法

Swift-从另一个ViewController插入TableView中的项目

使用 UIView 中的按钮从另一个 ViewController 触发方法