2014-08-31 2 views
7

Я новичок в программировании & Swift, и я пытаюсь понять, как передавать данные между двумя контроллерами представлений (без segue) с протоколами и делегатами.Попытка понять протокол/делегатов в Swift

У меня есть контроллер просмотра (VIEW A), в котором есть текстовое поле и кнопка. Когда пользователь нажимает на эту кнопку, он должен затем показывать этот текст в метке в другом контроллере просмотра (VIEW B).

Я не могу получить ярлык, чтобы показать текст - я был бы признателен за объяснение того, что требуется для выполнения этой работы.

Большое спасибо!

import UIKit 

      protocol sendNameToViewB { 

       func showNameLabel(name:String) 
      } 

      class ViewA: UIViewController { 

       var delegate: sendNameToViewB? 

       @IBOutlet weak var textField: UITextField! 

       @IBAction func addButton(sender: AnyObject) { 
        delegate?.showNameLabel(textField.text) 

       } 
       override func viewDidLoad() { 
        super.viewDidLoad() 

        // Do any additional setup after loading the view, typically from a nib. 
       } 
       override func didReceiveMemoryWarning() { 
        super.didReceiveMemoryWarning() 
        // Dispose of any resources that can be recreated. 
       } 


      } 

      class ViewB: UIViewController, sendNameToViewB { 

       @IBOutlet weak var theLabel: UILabel! 

       func showNameLabel(name: String) { 
        theLabel.text = name 
       } 
      } 

VIEW CONTROLLERS

ответ

8

Во-первых, обратите внимание: Ваши имена для контроллеров отображения должна включать в себя "ViewController" в названии. Существует совершенно другой набор классов, которые наследуются от UIView. Назначение имени контроллера просмотра только ViewA делает его похожим на то, что ваш класс является просто представлением вместо контроллера вида. Представления находятся в совершенно другом слое вашего приложения.

Теперь, чтобы передать данные другому объекту, ваше первое требование - иметь ссылку между ними. Эта ссылка может быть настроена в любом направлении.

Одна из возможностей заключается в том, чтобы ViewControllerA сохранял ссылку на ViewControllerB. С помощью этой ссылки ViewControllerA может вызывать метод на ViewControllerB при нажатии кнопки, которая принимает данные, которые вы хотите передать в качестве аргумента.

class ViewControllerA: UIViewController { 
    @IBOutlet weak var viewControllerB: ViewControllerB! 

    @IBAction func addButton(sender: AnyObject) { 
     self.viewControllerB.showNameLabel(textField.text) 
    } 
} 

Другая возможность заключается в использовании шаблона делегата, как предлагает ваш заголовок. Это будет включать ViewControllerB со ссылкой на ViewControllerA. Предпочтительно, это не связано с непосредственным знанием класса ViewControllerA, а вместо этого через протокол. Протокол будет определять метод, который возвращает данные, которые вы хотите «передать» в ViewControllerB. Таким образом, ViewContollerB может вызывать метод протокола в своем «делетете» (который, вероятно, будет ViewControllerA), чтобы получить нужные ему данные.

protocol ViewControllerBDelegate { 
    func requiredText() -> String 
} 

class ViewControllerB: UIViewController { 
    @IBOutlet weak var delegate: ViewControllerBDelegate? 

    override func viewDidLoad() { 
     if let actualDelegate = self.delegate { 
      self.theLabel.text = actualDelegate.requiredText() 
     } 
    } 
} 

Какой именно метод вы выбираете, действительно зависит от того, что вам нужно в этом случае. В шаблоне делегата лучше держать ваши объекты менее связанными друг с другом, но если вам уже нужно «запускать» вещи на ViewControllerB из ViewControllerA, возможно, потребуется более прямой метод.

+0

Спасибо за помощь @drewag! –

+1

Будет ли «прямой» метод не создавать новый экземпляр ViewControllerB? Кроме того, мне пришлось использовать «var tabbarViewController: TabBarViewController = TabBarViewController()» вместо того, как вы его поместили, не работало (переменная осталась нулевой) –

+0

@ByronCoetsee & OP, у вас есть какие-то ресурсы, которые будут углубляться в глубину какой метод преследовать? Когда требуется соединение? и т.д. Спасибо! –

Смежные вопросы