[Swift-UIKit]메모 만들기-2

sai06266·2023년 8월 27일

Swift

목록 보기
5/10

8/26.

다음으로는 메모 순서 이동과 메모 수정을 구현하였다.

[메모 순서 이동]

edit버튼을 통해 메모의 순서도 바꿀 수 있는데,

    override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
        let memoToMove = Memo.MemoList[(fromIndexPath as NSIndexPath).row]
        Memo.MemoList.remove(at: (fromIndexPath as NSIndexPath).row)
        Memo.MemoList.insert(memoToMove, at: (to as NSIndexPath).row)
    }
}

위와 같은 함수를 정의하면 메모의 순서를 쉽게 변경할 수 있다.
단순하게 해당 메모를 MemoList에서 제거한 후 순서에 맞게 추가하면 된다.

[메모 수정]

메모를 수정하기 위해서는 목록에서 메모를 클릭했을 때 새로운 view controller로 연결하고 메모의 내용을 전달해줘야한다.

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let selectedMemo = Memo.MemoList[indexPath.row]
        if let editVC = storyboard?.instantiateViewController(withIdentifier: "MemoEditViewController") as? MemoEditViewController {
            editVC.memoToEdit = selectedMemo
            editVC.delegate = self // 델리게이트 설정
            navigationController?.pushViewController(editVC, animated: true)
        }
    }

먼저 선택된 행에 해당하는 메모를 가져오고,
미리 설정해둔 storyboard ID에 해당하는 뷰 컨트롤러 인스턴스를 생성한다.
해당 뷰컨트롤러의 memoToEdit변수에 메모를 전달하고,
편집 완료의 신호를 받을 delegate를 선언해준다.
마지막으로 뷰컨트롤러를 푸시해 화면 전환을 할 수 있도록 해준다.

메모를 수정할 뷰컨트롤러에 프로토콜을 정의함으로서 수정이 완료되었을 때 메모를 전달할 수 있도록 한다.

protocol MemoEditDelegate: AnyObject {
    func memoEditViewController(_ controller: MemoEditViewController, didFinishEditing updatedMemo: Memo)
}
class MemoEditViewController: UIViewController {

    @IBOutlet var memoTextView: UITextView!
    //delegate를 통해 메모가 수정되었음을 다른 뷰에게 알림
    weak var delegate: MemoEditDelegate?
    //메모의 정보를 받는 변수 추가
    var memoToEdit: Memo!
    override func viewDidLoad() {
        super.viewDidLoad()
        //수정하기 전 메모의 내용 표시
        memoTextView.text = memoToEdit.content
    }
    
    @IBAction func btnSave(_ sender: UIBarButtonItem) {
        guard let updatedContent = memoTextView.text, !updatedContent.isEmpty else {
            return
        }
        memoToEdit.update(content: updatedContent)
        delegate?.memoEditViewController(self, didFinishEditing: memoToEdit)
        //이전 화면으로 돌아가기
        navigationController?.popViewController(animated: true)
    }
}

전의 뷰컨트롤러에서 받은 text의 내용을 memoTextView에 전달하고 사용자가 내용을 수정하고 완료 버튼을 누르면 btnSave액션 함수가 수행된다.
guard문은 메모의 내용이 달라졌는지 확인하는 과정으로 달라진 내용이 없다면(isEmpty하다면) return하여 함수를 종료하게 됩니다.
달라진 내용이 있다면, 아까 정의하였던 프로토콜을 통해 바뀐 메모의 내용을 전달하고 뷰컨트롤러를 pop하여 원래 화면으로 돌아갈 수 있도록 합니다.

원래의 뷰컨트롤러에서도 MemoEditDelegate프로토콜에 대한 정의가 필요한데,
extension을 통해 정의한다.

extension MemoTableViewController: MemoEditDelegate {
    func memoEditViewController(_ controller: MemoEditViewController, didFinishEditing updatedMemo: Memo) {
        if let index = Memo.MemoList.firstIndex(where: { $0 === updatedMemo }) {
            tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
        }
    }
}

쉽게 말하면 전달받은 메모와 같은 객체인 원래의 메모를 찾아 내용을 변경하고 리로드한다.

0개의 댓글