从swift中的另一个视图控制器的实例访问视图控制器

时间:2021-01-13 16:03:08

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

我试图将数据从一个视图控制器的textfield传输到另一个视图控制器的label。

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!

谢谢你的帮助!

3 个解决方案

#1


16  

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

Add a new Cocoa Touch class file in your project, name it FirstViewController and 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 SecondViewController and 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 UIButton or a UIBarButtonItem. Set the name of the first view controller to FirstViewController and the name of the second view controller to SecondViewController. Create a UITextField in the first view controller. Create a UILabel in the second view controller. Link the textfield and the label to their respective declarations in FirstViewController and SecondViewController.

在故事板中,在UINavigationController中嵌入第一个视图控制器。用UIButton或UIBarButtonItem将第一个视图控制器链接到第二个视图控制器。将第一个视图控制器的名称设置为FirstViewController,将第二个视图控制器的名称设置为SecondViewController。在第一个视图控制器中创建一个UITextField。在第二个视图控制器中创建一个UILabel。将textfield和label链接到FirstViewController和SecondViewController中的各自声明。


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

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

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

Add a new Cocoa Touch class file in your project, name it FirstViewController and 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 SecondViewController and 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 UIButton or a UIBarButtonItem. Set the name of the first view controller to FirstViewController and the name of the second view controller to SecondViewController. Create a UILabel in the first view controller. Create a UITextField in the second view controller. Link the textfield and the label to their respective declarations in FirstViewController and SecondViewController.

在故事板中,在UINavigationController中嵌入第一个视图控制器。用UIButton或UIBarButtonItem将第一个视图控制器链接到第二个视图控制器。将第一个视图控制器的名称设置为FirstViewController,将第二个视图控制器的名称设置为SecondViewController。在第一个视图控制器中创建一个UILabel。在第二个视图控制器中创建一个UITextField。将textfield和label链接到FirstViewController和SecondViewController中的各自声明。

#2


6  

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.

伊马努·佩提特和奥斯卡·斯旺罗斯已经回答对了。不过,还有一种替代方法,我不得不使用它来在两个视图控制器之间传输数据,而无需使用连接它们的segue。

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.

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

#3


3  

You need to create a Segue between View Controllers:

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

  1. On your Storyboard, select ViewController A.
  2. 在你的故事板上,选择ViewController A。
  3. While holding the Control, click ViewController A, drag and drop the blue line to ViewController B. If ViewController A is embedded in a NavigationController, select "show" from the menu that appears when you let go. Otherwise, select "present modally."
  4. 在保持控件的同时,单击ViewController A,将蓝色线拖放到ViewController b中。如果ViewController A嵌入到NavigationController中,那么在你放手时出现的菜单中选择“show”。否则,选择“程序地。”
  5. 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").
  6. 在故事板上选择Segue,在实用工具面板上,转到属性检查器,为你的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):

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

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

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

要将值传递给视图控制器B,重写视图控制器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
    }
}

Pretty straightforward.

非常简单。

Note that for this to work, your ViewController B class 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.

希望这个有帮助。

#1


16  

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

Add a new Cocoa Touch class file in your project, name it FirstViewController and 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 SecondViewController and 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 UIButton or a UIBarButtonItem. Set the name of the first view controller to FirstViewController and the name of the second view controller to SecondViewController. Create a UITextField in the first view controller. Create a UILabel in the second view controller. Link the textfield and the label to their respective declarations in FirstViewController and SecondViewController.

在故事板中,在UINavigationController中嵌入第一个视图控制器。用UIButton或UIBarButtonItem将第一个视图控制器链接到第二个视图控制器。将第一个视图控制器的名称设置为FirstViewController,将第二个视图控制器的名称设置为SecondViewController。在第一个视图控制器中创建一个UITextField。在第二个视图控制器中创建一个UILabel。将textfield和label链接到FirstViewController和SecondViewController中的各自声明。


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

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

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

Add a new Cocoa Touch class file in your project, name it FirstViewController and 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 SecondViewController and 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 UIButton or a UIBarButtonItem. Set the name of the first view controller to FirstViewController and the name of the second view controller to SecondViewController. Create a UILabel in the first view controller. Create a UITextField in the second view controller. Link the textfield and the label to their respective declarations in FirstViewController and SecondViewController.

在故事板中,在UINavigationController中嵌入第一个视图控制器。用UIButton或UIBarButtonItem将第一个视图控制器链接到第二个视图控制器。将第一个视图控制器的名称设置为FirstViewController,将第二个视图控制器的名称设置为SecondViewController。在第一个视图控制器中创建一个UILabel。在第二个视图控制器中创建一个UITextField。将textfield和label链接到FirstViewController和SecondViewController中的各自声明。

#2


6  

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.

伊马努·佩提特和奥斯卡·斯旺罗斯已经回答对了。不过,还有一种替代方法,我不得不使用它来在两个视图控制器之间传输数据,而无需使用连接它们的segue。

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.

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

#3


3  

You need to create a Segue between View Controllers:

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

  1. On your Storyboard, select ViewController A.
  2. 在你的故事板上,选择ViewController A。
  3. While holding the Control, click ViewController A, drag and drop the blue line to ViewController B. If ViewController A is embedded in a NavigationController, select "show" from the menu that appears when you let go. Otherwise, select "present modally."
  4. 在保持控件的同时,单击ViewController A,将蓝色线拖放到ViewController b中。如果ViewController A嵌入到NavigationController中,那么在你放手时出现的菜单中选择“show”。否则,选择“程序地。”
  5. 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").
  6. 在故事板上选择Segue,在实用工具面板上,转到属性检查器,为你的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):

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

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

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

要将值传递给视图控制器B,重写视图控制器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
    }
}

Pretty straightforward.

非常简单。

Note that for this to work, your ViewController B class 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.

希望这个有帮助。