Pertanyaan pemula tentang meneruskan data di antara pengontrol tampilan

Aug 19 2020

Saya mencoba membuat ulang aplikasi Notes di iOS. Saya telah membuat Pengontrol Tampilan awal yang hanya tampilan tabel. Seorang pengguna dapat pergi ke Pengontrol Tampilan Detail untuk membuat catatan baru dengan bagian Judul dan Isi. Ketika mereka mengklik Selesai, saya ingin memanipulasi tableView dengan detail catatan.

Saya kesulitan menyimpan detail dari apa yang dimasukkan pengguna untuk digunakan pada pengontrol tampilan awal saya.

Inilah kelas Notes saya yang mendefinisikan data catatan:

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

Berikut adalah pengontrol Tampilan Detail tempat pengguna dapat memasukkan detail Catatan:

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

Saya juga memiliki array pada pengontrol tampilan awal saya juga. Saya rasa saya membutuhkan yang ini untuk menyimpan data catatan untuk ditampilkan di tableView (dan mungkin tidak memerlukan yang ada di pengontrol Detail View saya?). TableView belum sepenuhnya diimplementasikan.

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
    }

Jawaban

goat_herd Aug 19 2020 at 10:12

Hanya menggunakan Delegate: Pertama buat protokol delegasi dengan func untuk mengirim kembali catatan ke viewController Anda

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

Selanjutnya tambahkan variabel delegasi ke DetailViewController, dan panggil func noteDataDidUpdate untuk mengirim data kembali ke viewController

class DetailViewController: UIViewController {
    weak var delegate: DetailViewControllerDelegate?

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

terakhir, setel variabel delegasi ke viewController dan terapkan ini di 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
    }
}