首页 > 解决方案 > 关于在视图控制器之间传递数据的初学者问题

问题描述

我正在尝试在 iOS 中重新创建 Notes 应用程序。我创建了一个初始视图控制器,它只是一个表视图。用户可以转到详细视图控制器以编写带有标题和正文部分的新注释。当他们单击完成时,我想使用注释的详细信息来操作 tableView。

我正在努力保存用户在我的初始视图控制器上输入的内容的详细信息。

这是我的 Notes 类,它定义了注释数据:

class Notes: Codable {
    var titleText: String?
    var bodyText: String?
}

这是 Detail View 控制器,用户可以在其中输入 Note 详细信息:

class DetailViewController: UIViewController {
    @IBOutlet var noteTitle: UITextField!
    @IBOutlet var noteBody: UITextView!
    
    var noteDetails: Notes?
    var noteArray = [Notes]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(updateNote))
        noteTitle.borderStyle = .none
    }
    
    @objc func updateNote() {
        noteDetails?.titleText = noteTitle.text
        noteDetails?.bodyText = noteBody.text
        noteArray.append(noteDetails!) // This is nil
                
//        not sure if this is the right way to send the details over
//        let vc = ViewController() 
//        vc.noteArray.append(noteDetails!)
        
        if let vc = storyboard?.instantiateViewController(identifier: "Main") {
        navigationController?.pushViewController(vc, animated: true)
        }
    }
}

我的初始视图控制器上也有一个数组。我想我需要这个来存储笔记数据以显示在 tableView 中(也许不需要我的 Detail View 控制器上的那个?)。tableView 显然还没有完全实现。

class ViewController: UITableViewController {
    
    var noteArray = [Notes]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        print(noteArray)
        
        self.navigationItem.setHidesBackButton(true, animated: true)
        
        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(composeNote))
    }
    
    @objc func composeNote() {
        if let dvc = storyboard?.instantiateViewController(identifier: "Detail") as? DetailViewController {
            
            navigationController?.pushViewController(dvc, animated: true)
        }
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        noteArray.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        
        return cell
    }

标签: swifttableview

解决方案


仅使用 Delegate:首先使用 func 创建委托协议以将注释发送回您的 viewController

protocol DetailViewControllerDelegate: AnyObject {
    func newNoteDidAdded(_ newNote: Note)
}

接下来将委托变量添加到 DetailViewController,并调用 func noteDataDidUpdate 将数据发送回 viewController

class DetailViewController: UIViewController {
    weak var delegate: DetailViewControllerDelegate?

    @objc func updateNote() {
        ....
        delegate?.newNoteDidAdded(newNote)
    }
}

最后,将委托变量设置为 viewController 并在 ViewController 中实现它

class ViewController: UIViewController {

    ....
    @objc func composeNote() {
        if let dvc = storyboard?.instantiateViewController(identifier: "Detail") as? DetailViewController {
            dvc.delegate = self
            navigationController?.pushViewController(dvc, animated: true)
        }
    }

}

extension ViewController: DetailViewControllerDelegate {
    func newNoteDidAdded(_ newNote: Note) {
        // do some thing with your new note
    }
}

推荐阅读