skip to Main Content

I am trying to clone iOS Note App. I am having an issue with passing data back from Viewcontroller to another Tableviewcontroller. (here from EditorViewController to MainViewController)

I have a Note class with Text and Date properties.

class Note: Codable {
    var text: String
    var modificationDate: Date
    
    init(text: String, modificationDate: Date) {
        self.text = text
        self.modificationDate = modificationDate
    }
}

TableView:

class MainViewController: UITableViewController {
    
    var notes = [Note]()

    @objc func createNoteTapped(noteIndex: Int) {
        if let vc = storyboard?.instantiateViewController(identifier: "EditorViewController") as? EditorViewController {
            navigationController?.pushViewController(vc, animated: true)
        }
    } 
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return notes.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        ...  
    }
}
    

and ViewController that should send Note data back to obove tableview.

class EditorViewController: UIViewController {
    
    var notes: [Note]!
    var noteIndex: Int!

    @IBOutlet var textView: UITextView!
    
    func setParameters(notes: [Note], noteIndex: Int) {
        self.notes = notes
        self.noteIndex = noteIndex
        notes.append(notes[noteIndex])
    }
    
    @objc func saveNote() {

     ...

    }

}

In the EditorViewcontroller I have a textview , I want to save text inside of it as a Note text, and load that Note into TableView when I tap saveNote. I am really stuck at it, how should I write saveNote function to do that? I appreciate your help.

2

Answers


  1. Instead of using the delegate pattern, you can use closures to pass data back and forward.

    in your EditorViewController create the call back closure as like

    class EditorViewController: UIViewController {
    
            var onCompletion: ((notes: [Note]) -> ())?
            var notes: [Note]!
            var noteIndex: Int!
    

    on your save note action set the saved data in the completion part as like

    @IBAction func saveNote() {
        onCompletion?(notes: notes)
                self.navigationController?.popViewController(animated: true)
    
    }
    

    finally process your data on MainViewController like as

       @objc func createNoteTapped(noteIndex: Int) {
        if let vc = storyboard?.instantiateViewController(identifier: "EditorViewController") as? EditorViewController {
             vc.onCompletion = { notes in
            // this will be executed when `saveNote(_:)` will be called
            print(notes)
            // refresh your tableview
        }
            navigationController?.pushViewController(vc, animated: true)
        }
    } 
    
    Login or Signup to reply.
  2. As i said in my comments you can create a protocol to pass the array of Note to your MainViewController

    protocol YourProtocolName {
        func updatedNotes(notes: [Note])
    }
    

    Then your MainViewController needs to implement this protocol

    extension MainViewController: YourProtocolName {
       func updatedNotes(notes: [Note]) {
          //Do whatever you need to do here
       }
    }
    

    After this you need to declare MainViewController as EditorViewController delegate adding weak var delegate: YourProtocolName in your EditorViewController class, and lastly you need to modify createNoteTapped function in MainViewController passing self as EditorViewController delegate

    @objc func createNoteTapped(noteIndex: Int) {
            if let vc = storyboard?.instantiateViewController(identifier: "EditorViewController") as? EditorViewController {
                vc.delegate = self
                navigationController?.pushViewController(vc, animated: true)
            }
        } 
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search