[iOS/Swift] (커스텀) 델리게이트 패턴 사용해보기

최정은·2023년 9월 1일
0

Swift

목록 보기
18/27
image.jpg1image.jpg2
  • 두 번째 페이지에서 이용자 정보를 수정했을 때, 전 화면으로 전환되고 첫 번째 페이지의 TableView의 정보가 변경된 정보를 표시하게끔 구현하려고 한다.

  • 일단 프로토콜을 생성한 뒤, 이용자를 추가하는 함수와 이용자를 수정했을 때 구현할 함수를 정의한다. 강한 순환 참조를 방지하기 위해, Class에서만 채택을 할 수 있는 프로토콜이라는 의미인 'AnyObject'를 추가하여 선언해준다. (이렇게 선언해줘야만 weak으로 선언해 줄 수 있음)
protocol MemberDelegate: AnyObject {
    
    func addNewMember(_ member: Member)
    func update(index: Int, _ member: Member)
}
  • delegate를 호출할 두 번째 페이지에서 아래와 같이 변수를 프로토콜 타입으로 생성한다. 이때 중요한 점은 첫 번째뷰와, 두 번째뷰가 서로가 서로를 가리키는 강한 순환 참조가 일어나기 때문에 weak으로 설정해주어야 된다.
final class DetailViewController: UIViewController {
    weak var delegate: MemberDelegate?
  • UPDATE 버튼을 클릭하였을 때 delegate가 동작하는 코드를 구현한다.
 @objc func saveButtonTapped(){
        
        // [1] 멤버가 없다면 (새로운 멤버를 추가하는 화면)
        if member == nil {
            ...
            
            // 델리게이트 방식으로 구현⭐️
            delegate?.addNewMember(newMember)
            
            
        // [2] 멤버가 있다면 (멤버의 내용을 업데이트 하기 위한 설정)
        } else {
            ...
            
            // 뷰에도 바뀐 멤버를 전달 (뷰컨트롤러 ==> 뷰)
            detailView.member = member
            
            // 델리게이트 방식으로 구현⭐️
            delegate?.update(index: memberId, member!)
        }
        
        // (일처리를 다한 후에) 전화면으로 돌아가기
        self.navigationController?.popViewController(animated: true)
    }
}
  • 첫 번째뷰에서 delegate를 채택하는 코드와, 함수를 정의해준다.
extension ViewController: UITableViewDelegate{
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        let detailVC = DetailViewController()
        detailVC.delegate = self
        detailVC.member = memberListManager[indexPath.row]
        navigationController?.pushViewController(detailVC, animated: true)
    }
}

extension ViewController: MemberDelegate{
    
    func addNewMember(_ member: Member) {
        memberListManager.makeNewMember(member)
        tableView.reloadData()
    }
    
    func update(index: Int, _ member: Member) {
        memberListManager.updateMemberInfo(index: index, member)
        tableView.reloadData()
    }
}

0개의 댓글