ios 快速访问另一个视图控制器的实例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25204255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:45:54  来源:igfitidea点击:

Access the instance of a Viewcontroller from another in swift

iosuiviewcontrollerswift

提问by McLawrence

I am trying to transfer data from the textfield of one View Controller to the label from another.

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

How can I call the View Controller instance from the code of the other View Controller? I'm working with storyboards thus I never created an instance of the View Controllers in the code? Are the instances automatically created? And what name do they have?

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

Thanks for your help!

谢谢你的帮助!

采纳答案by Imanou Petit

1. If the view controller containing the textfield can call (with a segue) the view controller containing the label...

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

Add a new Cocoa Touch class file in your project, name it FirstViewControllerand set the following code in it:

在您的项目中添加一个新的 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
    }

}

Add a new Cocoa Touch class file in your project, name it SecondViewControllerand set the following code in it:

在您的项目中添加一个新的 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
    }

}

In the Storyboard, embed the first view controller in a UINavigationController. Link the first view controller to the second with a UIButtonor a UIBarButtonItem. Set the name of the first view controller to FirstViewControllerand the name of the second view controller to SecondViewController. Create a UITextFieldin the first view controller. Create a UILabelin the second view controller. Link the textfield and the label to their respective declarations in FirstViewControllerand SecondViewController.

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



2. If the view controller containing the label can call (with a segue) the view controller containing the textfield...

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

Here, this is a perfect protocol/delegate case. You may find a lot of stuff on StackOverflow dealing with this. However, here is a rough example.

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

Add a new Cocoa Touch class file in your project, name it FirstViewControllerand set the following code in it:

在您的项目中添加一个新的 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
    }

}

Add a new Cocoa/Cocoa Touch class file in your project, name it SecondViewControllerand set the following code in it:

在您的项目中添加一个新的 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)
    }

}

In the Storyboard, embed the first view controller in a UINavigationController. Link the first view controller to the second with a UIButtonor a UIBarButtonItem. Set the name of the first view controller to FirstViewControllerand the name of the second view controller to SecondViewController. Create a UILabelin the first view controller. Create a UITextFieldin the second view controller. Link the textfield and the label to their respective declarations in FirstViewControllerand SecondViewController.

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

回答by Jo?o Neves

Imanou Petit and Oscar Swanros already answered correctly. However there is an alternative which is rather "hacky" that I had to use to transfer data between 2 view controllers without a segue connecting them.

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

To obtain the root view controller of your app you can do:

要获取您的应用程序的根视图控制器,您可以执行以下操作:

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

From there you can get any view controller you want. For instance, if you want the second child view controller of the root view controller then you would do:

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

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

Keep in mind that this approach is rather "hacky" and probably violates the best coding practices.

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

回答by Oscar Swanros

You need to create a Segue between View Controllers:

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

  1. On your Storyboard, select ViewController A.
  2. While holding the Control, click ViewController A, drag and drop the blue line to ViewController B. If ViewController Ais embedded in a NavigationController, select "show" from the menu that appears when you let go. Otherwise, select "present modally."
  3. Select the Segue on your Storyboard, and on the Utilities Panel, go to the Attributes Inspector and assign an Identifier for your segue (e.g.: "DetailSegue").
  1. 在您的故事板上,选择ViewController A
  2. 按住 的同时Control单击ViewController A,将蓝线拖放到ViewController B。如果ViewController A嵌入在 中NavigationController,请从松开时出现的菜单中选择“显示”。否则,选择“模态呈现”。
  3. 在 Storyboard 上选择 Segue,然后在 Utilities 面板上,转到 Attributes Inspector 并为您的 Segue 分配一个标识符(例如:“DetailSegue”)。

Now, when you want to trigger the segue on ViewController A, you just need to call (maybe on the tap of a button):

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

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

To pass a value to ViewController B, override the prepareForSegue:sendermethod on ViewController A:

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

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

Pretty straightforward.

很简单。

Note that for this to work, your ViewController Bclass should look something like this:

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

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

    override func viewDidLoad() {
        super.viewDidLoad()

        label.text = text!
    }
}

Hope this helps.

希望这可以帮助。