뷰 컨트롤러 간 데이터 전달에 대한 초급 질문

Aug 19 2020

iOS에서 Notes 앱을 다시 만들려고합니다. 테이블 뷰인 초기 뷰 컨트롤러를 만들었습니다. 사용자는 상세보기 컨트롤러로 이동하여 제목 및 본문 섹션이있는 새 메모를 작성할 수 있습니다. Done을 ​​클릭하면 메모의 세부 정보로 tableView를 조작하고 싶습니다.

사용자가 초기 뷰 컨트롤러에서 사용하기 위해 입력 한 세부 정보를 저장하는 데 어려움을 겪고 있습니다.

다음은 메모 데이터를 정의하는 내 Notes 클래스입니다.

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

다음은 사용자가 노트 세부 정보를 입력 할 수있는 Detail View 컨트롤러입니다.

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
    }

답변

goat_herd Aug 19 2020 at 10:12

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