ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [UIKit] 화면전환 코드를 프로토콜로 사용하기
    iOS 2024. 6. 4. 18:56

     

    UIKit을 공부하던 중 여러 뷰 컨트롤러에서 반복적으로 사용되는 화면 전환 코드들을 프로토콜로 작성해 한 파일에서 관리하면 보다 효율적인 코드를 작성할 수 있겠다는 생각이 들었다.

     

    그러려면 프로젝트에 작성된 ViewController들을 부모인 UIViewController타입의 파라미터에 할당할 때 다운캐스팅을 하지 않아도 내부에 작성된 코드들이 정상적으로 실행될 수 있는 지 확인이 필요해 먼저 playground에서 테스트 코드를 작성해보았다.

     

     

    UIViewController 타입으로 업캐스팅된 TestViewController를 자신의 타입으로 타입 검사시 일치하는 것으로 인식된다.

     

     

    테스트 결과를 바탕으로 아래와 같이 프로토콜을 작성하였다

     

     

    화면 전환 프로토콜

     

    protocol ViewTransition {
       
        func pushAfterView(view: UIViewController, backButton: Bool, animated: Bool)
        
        func presentAfterView(view: UIViewController, presentationStyle: UIModalPresentationStyle, animated: Bool)
        
        func navigationPresentAfterView(view: UIViewController, style: UIModalPresentationStyle, animated: Bool)
        
        func popBeforeView(animated: Bool)
       
        func popToBeforeView(_ view: UIViewController, animated: Bool)
        
        func popToRootView(animated: Bool)
    }

     

     

    또한 이 프로토콜의 가상함수들을 일일이 각각의 ViewController에서 구현하기 보다는 모든 ViewController들의 부모타입인 UIViewController의 Extension으로 구현하면 앞으로 추가적인 구현없이 정의된 함수를 호출하는 것만으로 화면전환을 수행할 수 있을 것으로 판단했다.

     

     

    ViewTransition 프로토콜을 UIViewController의 Extension으로 구현

     

    extension UIViewController: ViewTransition {
    
        func pushAfterView(view: UIViewController, backButton: Bool, animated: Bool) {
            if !backButton {
                view.navigationItem.hidesBackButton = true
            }
            self.navigationController?.pushViewController(view, animated: animated)
        }
        
        func presentAfterView(view: UIViewController, presentationStyle: UIModalPresentationStyle, animated: Bool) {
            view.modalPresentationStyle = presentationStyle
            self.present(view, animated: animated)
        }
        
        func navigationPresentAfterView(view: UIViewController, style: UIModalPresentationStyle, animated: Bool) {
            let nav = UINavigationController(rootViewController: view)
            nav.modalPresentationStyle = style
            present(nav, animated: animated)
        }
        
        func popBeforeView(animated: Bool) {
            navigationController?.popViewController(animated: animated)
        }
        
        func popToBeforeView(_ view: UIViewController, animated: Bool) {
            navigationController?.popToViewController(view, animated: animated)
        }
        
        func popToRootView(animated: Bool) {
            navigationController?.popToRootViewController(animated: true)
        }
    }

     

     

    이제 ViewController간의 화면전환 시 별도의 구현없이 위 함수들을 호출하는 것만으로 원하는 ViewController로 전환할 수 있게 되었다.

     

     

    사용예시

     

    func goNextViewController() {
            let vc = NextViewController()
            vc.delegate = self
            pushAfterView(view: vc, backButton: true, animated: true)
    }

     

    func updateAndGoBeforeView() { 
            delegate?.updateUserProfile(nickName: nickName, profileImage: image)
            popBeforeView(animated: true)
    }

     

     

    화면전환 코드가 많은 코드라인을 차지하진 않아도 이를 프로토콜로 만들어 직접 사용해보니 몇 가지 장점들이 있었다.

     

     

    1.  모든 뷰 컨트롤러에서 사용되는 화면전환 코드들을 한 파일에서 관리할 수 있어 코드 관리가 용이
    2.  구현부가 한 파일에만 존재하여 각 뷰 컨트롤러의 코드라인 수 감소
    3.  코드의 재사용성이 높아져 한 번의 코드작성으로 이후 반복되는 화면전환 케이스에 실수 없이 대응할 수 있음

     

     

    iOS 공부를 시작한 지 이제 막 한 달차인 상태에서 이렇게 직접 간단한 프로토콜을 만들어 사용해 보니 낯설기만 했던 프로토콜과 조금 더 가까워진 느낌이 든다.

    Protocol Oriented Programming을 지향하는 Swift를 더 Swift스럽게 사용할 수 있게 되도록 앞으로도 더 알아가보고 싶다.

    댓글

All Posts are written by Tunastorm