prepareForSegue是在视图控制器之间传递值的正确方法

Meh*_*yer 6 ios segue swift

我正在尝试学习Swift,我正在尝试开发着名的音符应用程序.

有一个绑定到tableview的数组和另一个用于添加注释的视图.在第二个视图中,textfieldshouldreturn事件触发segue并返回tableview.

我想知道这是否正确.因为通过这种方式,我正在操纵另一个视图控制器中的变量.我不是MVC大师,但我觉得这是错的.这是我的代码片段:

func textFieldShouldReturn(textField: UITextField) -> Bool {

    self.performSegueWithIdentifier("backSegue", sender: self)
    return true
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if(segue.identifier == "backSegue"){
        let navController = segue.destinationViewController as UINavigationController;
        let myController = navController.topViewController as NotesTableViewController;
        if(self.ourTextField?.text != nil || self.ourTextField?.text != ""){
            myController.notes.append(self.ourTextField?.text ?? "");
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

vac*_*ama 7

你的问题不是关于prepareForSegue视图控制器之间的关系.你的设计"感觉不对"的原因在于它.问题是你的笔记编写视图控制器对使用它的视图控制器了解太多,因为它直接操作来自调用视图控制器的变量.为了直接操作变量,它必须知道调用者的类.

为什么这是个问题?它使您的笔记编写视图控制器更少可重用.如果您正确编写了笔记编写视图控制器,那么您可以在其他应用程序中重复使用它.为了使其可重用,您需要将笔记写入视图控制器与调用者分离 - 它必须不知道究竟是谁正在调用它.

所以问题就变成了,如果我不知道是谁给我打电话,如何将数据传回给来电者?答案是代表团.

代表团这样工作:

  1. 您创建了一个协议,该协议描述了该协议的实现者将实现的一种或多种方法.在您的情况下,您可以使用NoteWriterDelegate实现该方法的协议takeNote(note: String).

    protocol NoteWriterDelegate {
        func takeNote(note: String)
    }
    
    Run Code Online (Sandbox Code Playgroud)

    在文件中将其与注释写入视图控制器一起定义.

  2. 您的笔记编写器将有一个指向委托的可选指针:

    weak var delegate: NoteWriterDelegate?
    
    Run Code Online (Sandbox Code Playgroud)
  3. 您需要将第一个视图控制器声明为NoteWriterDelegate:

    class ViewController: UITableViewController, NoteWriterDelegate
    
    Run Code Online (Sandbox Code Playgroud)
  4. 然后在第一个视图控制器中实现所需的方法:

    func takeNote(note: String) {
        notes.append(note)
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 当您prepareForSegue准备移动笔记编写视图控制器时,您将自己作为代理传递:

    destinationViewController.delegate = self
    
    Run Code Online (Sandbox Code Playgroud)
  6. 在便笺写入视图控制器中,当您有一个要传递给调用者的注释时,您可以调用takeNote该委托:

    delegate?.takeNote(self.ourTextField?.text ?? "")
    
    Run Code Online (Sandbox Code Playgroud)

通过这样做,你的笔记作者只知道它正在与一个人交谈NoteWriterDelegate.如果你想在将来重用它,你只需将你的笔记编写器类放到另一个项目中,实现委托,它就可以在你不必触及笔记编写器类中的代码的情况下工作.