คำถามเริ่มต้นเกี่ยวกับการส่งผ่านข้อมูลระหว่างตัวควบคุมมุมมอง

Aug 19 2020

ฉันพยายามสร้างแอพ Notes ใหม่ใน iOS ฉันได้สร้าง View Controller เริ่มต้นซึ่งเป็นเพียงมุมมองตาราง ผู้ใช้สามารถไปที่ตัวควบคุมมุมมองรายละเอียดเพื่อเขียนบันทึกใหม่ด้วยหัวข้อและส่วนเนื้อหา เมื่อพวกเขาคลิกเสร็จสิ้นฉันต้องการจัดการ tableView ด้วยรายละเอียดของโน้ต

ฉันกำลังดิ้นรนในการบันทึกรายละเอียดของสิ่งที่ผู้ใช้ป้อนเพื่อใช้ในตัวควบคุมมุมมองเริ่มต้นของฉัน

นี่คือคลาส Notes ของฉันซึ่งกำหนดข้อมูลโน้ต:

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

นี่คือตัวควบคุมมุมมองรายละเอียดที่ผู้ใช้สามารถป้อนรายละเอียดหมายเหตุ:

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 (และอาจไม่จำเป็นต้องใช้ตัวควบคุมมุมมองรายละเอียดของฉัน?) เห็นได้ชัดว่า 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
    }

คำตอบ

goat_herd Aug 19 2020 at 10:12

เพียงแค่ใช้ Delegate: ขั้นแรกให้สร้างโปรโตคอลผู้รับมอบสิทธิ์ด้วย func เพื่อส่งบันทึกกลับไปยัง viewController ของคุณ

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

จากนั้นเพิ่มตัวแปร delegate ไปยัง DetailViewController และเรียก func noteDataDidUpdate เพื่อส่งข้อมูลกลับไปที่ viewController

class DetailViewController: UIViewController {
    weak var delegate: DetailViewControllerDelegate?

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

สุดท้ายตั้งค่าตัวแปร delegate เป็น 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
    }
}