Подтвердить что ты не робот

Получите доступ к экземпляру Viewcontroller из другого в swift

Я пытаюсь передать данные из текстового поля одного контроллера View на метку из другого.

Как я могу вызвать экземпляр View Controller из кода другого View Controller? Я работаю с раскадными версиями, поэтому я никогда не создавал экземпляр контроллеров View в коде? Созданы ли экземпляры автоматически? И какое имя у них есть?

Спасибо за вашу помощь!

4b9b3361

Ответ 1

1. Если контроллер вида, содержащий текстовое поле, может вызвать (с помощью segue) контроллер представления, содержащий метку...

Добавьте новый новый файл Cocoa Touch class в свой проект, назовите его 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
    }

}

В раскадровке вставьте первый контроллер представления в UINavigationController. Свяжите первый контроллер представления со вторым с помощью UIButton или UIBarButtonItem. Задайте имя первого контроллера представления FirstViewController и имя второго контроллера просмотра SecondViewController. Создайте UITextField в первом контроллере представления. Создайте UILabel во втором контроллере представления. Свяжите текстовое поле и метку с соответствующими объявлениями в FirstViewController и SecondViewController.

2. Если контроллер вида, содержащий метку, может вызвать (с помощью segue) контроллер вида, содержащий текстовое поле...

Здесь это идеальный протокол/делегирование. Вы можете найти много вещей в StackOverflow, связанных с этим. Однако здесь приведен пример.

Добавьте новый новый файл Cocoa Touch class в свой проект, назовите его 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)
    }

}

В раскадровке вставьте первый контроллер представления в UINavigationController. Свяжите первый контроллер представления со вторым с помощью UIButton или UIBarButtonItem. Задайте имя первого контроллера представления FirstViewController и имя второго контроллера просмотра SecondViewController. Создайте UILabel в первом контроллере представления. Создайте UITextField во втором контроллере представления. Свяжите текстовое поле и метку с соответствующими объявлениями в FirstViewController и SecondViewController.

Ответ 2

Иману Пети и Оскар Суонрос уже ответили правильно. Однако есть альтернатива, которая довольно "хакерская", которую я должен был использовать для передачи данных между двумя контроллерами представлений без их подключения.

Чтобы получить контроллер корневого представления вашего приложения, вы можете:

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

Оттуда вы можете получить любой контроллер вида, который вы хотите. Например, если вы хотите, чтобы второй контроллер дочерних представлений контроллера корневого представления вы делали:

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

Имейте в виду, что этот подход довольно "взломан" и, вероятно, нарушает наилучшие методы кодирования.

Ответ 3

Вам нужно создать Segue между контроллерами представления:

  • На вашей раскадровке выберите ViewController A.
  • Удерживая Control, нажмите ViewController A, перетащите синюю линию на ViewController B. Если ViewController A встроен в NavigationController, выберите "показать" из меню, которое появляется, когда вы отпускаете. В противном случае выберите "present modally".
  • Выберите Segue на вашей раскадровке и на панели "Утилиты", перейдите к инспектору атрибутов и назначьте идентификатор для вашего сеанса (например, "DetailSegue" ).

Теперь, когда вы хотите вызвать segue на ViewController A, вам просто нужно позвонить (возможно, нажатием кнопки):

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

Чтобы передать значение 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
    }
}

Довольно просто.

Обратите внимание, что для этого ваш класс ViewController B должен выглядеть примерно так:

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

    override func viewDidLoad() {
        super.viewDidLoad()

        label.text = text!
    }
}

Надеюсь, что это поможет.