Pregunta de principiante sobre el paso de datos entre controladores de vista

Aug 19 2020

Estoy tratando de recrear la aplicación Notes en iOS. Creé un controlador de vista inicial que es solo una vista de tabla. Un usuario puede ir a un controlador de vista de detalles para componer una nueva nota con una sección de título y cuerpo. Cuando hacen clic en Listo, quiero manipular tableView con los detalles de la nota.

Tengo problemas para guardar los detalles de lo que el usuario ingresó para usar en mi controlador de vista inicial.

Aquí está mi clase de Notas que define los datos de las notas:

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

Aquí está el controlador de vista detallada donde un usuario puede ingresar detalles de la nota:

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)
        }
    }
}

También tengo una matriz en mi controlador de vista inicial. Creo que necesito este para almacenar datos de notas para mostrar en TableView (¿y tal vez no necesito el que está en mi controlador de vista de detalles?). El tableView obviamente aún no está completamente implementado.

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
    }

Respuestas

goat_herd Aug 19 2020 at 10:12

Simplemente usando Delegate: Primero cree un protocolo de delegado con una función para enviar una nota a su viewController

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

A continuación, agregue la variable delegada a DetailViewController y llame a func noteDataDidUpdate para enviar datos de vuelta a viewController.

class DetailViewController: UIViewController {
    weak var delegate: DetailViewControllerDelegate?

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

finalmente, establezca la variable delegada en viewController e implemente esto en 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
    }
}