(Swift) - ProtocolDelegate 로 dismiss

JSLee·2021년 12월 21일
0

Delegation Pattern

이번에!
프로젝트를 하던 중 View전환에 대해서 큰 고민을 하게 되었습니다!!

예를 들어 A ViewController 에서 B로 전환되고 B에서 작업한 데이터를 가지고 다시 A로 올경우
물론 이렇게 말로 이야기 할경우에는 쉬워보여요..ㅎㅎ

그래서 저도 처음엔 그냥 self.dismiss하면 되는거 아니야?
했었죠..ㅎㅎ 그런데 혹시 경험하신 분들 계실지 모르겠지만 A에 데이터들이 제대로 전달이 안되는 경우가 많습니다 그리고 원인모를 크러쉬들이 자주 발생하구용!

또한 그리고 A컨트롤러에 테이블뷰나 , 콜렉션 뷰들이 있거나 할때 문제가 더 심각해집니다 ㅠㅠ
그래서 저는 이번엔 delegate 패턴을 사용했습니다.

이번에 개발중인 프로젝트입니다.
진행은 이런식으로 그림 그리기 전 SetupVC에서 UICollectionViewCompositionalLayout 로 설정된 cell을 탭하게 되면
뷰가 B로 이동되고
그곳에서 작업을 한뒤 액션의 따라서 데이터를 가지고 오거나 가지고 오지 않거나로 나뉘게 되는겁니다.

//MARK: - CollectionViewDelegate
extension SetUpViewController : UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let vc = DrawViewController(user: user, section: indexPath.section)
        vc.delegate = self
        let navi = UINavigationController(rootViewController: vc)
        navi.modalPresentationStyle = .fullScreen
        self.present(navi, animated: true, completion: nil)
    }
}

setUpViewController 즉 A 에서 didSelectItemAt 으로 인해
클릭된 cell의 Section의 맞는 value를 부여받아 뷰가 전환됩니다!
보통은 indexPath.row 를 쓰지만 저는 CompositionalLayout로 만든 collectionView 이기 때문에 Section으로 그값을 나눴어요!!
그래서 Section의 값을 주는겁니다 !

vc.delegate = self

자 쉽게 말해서 이게 리모콘 이라고 생각하시면되요!
A와 B를 이어주는 매개체 인것이쥬!

self.present(navi, animated: true, completion: nil)

자~ 이제 뷰가 전환이 되었습니다 프레젠트로용!

그럼!

뷰가 셋업이 되고!

 func configure() {
        view.backgroundColor = .white
        switch section {
        case 0 :
            title = "ThumbNail"
        case 1 :
            title = "PAGE-1"
        case 2 :
            title = "PAGE-2"
        case 3 :
            title = "PAGE-3"
        default :
            title = "PAGE-4"
        }
    }

이런식으로 같이 넘어온 Section으로 타이틀 값도 바꿔줄수 있습니다 ㅎㅎ
그럼 그림을 그렸다구 치고!! 업로드 되었을때!!
뷰가 닫히는 부분을 보기전에 먼저 protocol을 살펴보겠습니다!

protocol DrawViewControllerDelegate : AnyObject {
    func vcDidFinish(_ vc : DrawViewController)
}
class DrawViewController: UIViewController , PKCanvasViewDelegate {
//MARK: - Properties
    var section : Int
    
    private var user : User
    
    weak var delegate : DrawViewControllerDelegate?

자 요로코롬 프로토콜이 있습니다 그안엔 함수가 하나 있죠!?
매게변수로 받는 타입은 DrawViewController 이구요
자 그리고 밑을 보시다 보면

  weak var delegate : DrawViewControllerDelegate?

이 delegate 라는 녀석이 저 프로토콜 함수를 실행시켜줄 친구입니다!
엇 근데 앞에 weak는 뭐지? 라고 생각하실수도 있습니다!!
위에 프로토콜을 자세히 보시면 프로토콜 타입을 AnyObject으로 받아줬는데요!
(전에는 class로 받았었는데 이젠 AnyObject 로 받아야된다고 하네용..ㅎ)
이걸 받아주었기 때문에 delegate가 weak 딱지를 달수 있는거에욥

weak : X - 인스턴스의 소유권을 갖게된다(강한참조), O - 소유권x(약한참조)

이부분은 메모리문제이기 때문에 나중에 한번더 다루겠습니다
일단은 이정도만 알고계시면 될것 같아요

그럼 delegate를 실행시켜볼까요?

self.delegate?.vcDIdFinish(Self)
를 보시게 되면 파라미터 값으로 Self 즉 해당 인스턴스를 보내게됩니다.
이제 이 프로토콜을 받아주어야겠지요?

extension SetUpViewController : UploadViewControllerDelegate {
    func vcDidFinish(_ vc: UploadViewController) {
        vc.dismiss(animated: true, completion: nil)
		collectionView.reloadData()
    }
}

다시 A 입니다.
보시면 프로토콜 델리게이트로 먼저 익스텐션 해주시고 함수를 위임받게 되겠죵?
그리고 파라미터로 넘어 vc 즉 전단계에서 작업했던 인스턴스를

vc.dismiss(animated: true, completion: nil)

A에서 dismiss해주는 겁니다 그럼 뷰를 닫는것이 B에서 닫는것이 아닌 A에서 닫아주는것이지요

이런 delegate 패턴은 정말 많이 사용됩니다
예를 들어 collectionViewController에서 cell에게 어떠한 값을 전달 받고싶을땐
Cell안에 delegateProtocol을 만들어 그 delegate를 통해서 값을 받기도 하고
아주 다양하게 사용되는것 같습니다!!

감사합니다!!

profile
iOS/Android/FE/BE

0개의 댓글