관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] containerVC와 ChildVC 다루는 방법, 투명 뷰 (PassThroughView) 본문

iOS 응용 (swift)

[iOS - swift] containerVC와 ChildVC 다루는 방법, 투명 뷰 (PassThroughView)

jake-kim 2021. 2. 3. 01:18

Container와 Child 구성

  • containerVC위에 Sub1 또는 Sub2를 올려지는 화면
  • containerVC위에 Sub1 올려가져 있지만 ContainerVC 버튼도 선택됨 (Sub1 view PassThroughView 지정한 ContainerVC child 구성되었기 때문)

파란색 view, 노란색 view는 각각 다른 SubViewController가 Container에 add되는 것

Main화면을 중심으로, sub1, sub2, ... 바뀌는 화면 관리

  • Main이라는 ContainerVC와 sub1VC, sub2VC, ... 들로 관리
  • Main화면을 계속 띄워놓고 그 위에 sub1VC, sub2VC가 덮어지는 형태이며 main과 sub 둘 다 보여지게 할 때 사용
  • 중요한 공통 로직들을 Main에서 하며, 재사용에 유리함
  • 예시) main에는 지도화면
    (main 화면은 항상 밑에 존재하며, postTask, permission, UserNotificationCenter와 같은것을 체크하고 있음 )
    sub화면이 위에 있어도, 중간에 permission이 필요하게되면 그 로직을 수행

ContainerVC위 ChildVC 형태 구현

  • 원리: ContainerVC에서 필요한 childVC를 addChild하여 사용, childVC의 view는 clear color이고 PassThroughView로 변환할 것 (childVC로 ContainerVC가 덮여져있지만, childVC에서 ContainerVC화면에 gesture접근할수 있도록 하기위함)
  • hitTest개념: ios-development.tistory.com/327
// PassThroughView 출처 : https://stackoverflow.com/questions/25238722/how-to-make-touch-events-affect-views-behind-a-container-view

class PassThroughCustomView: UIView {

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
         // Get the hit view we would normally get with a standard UIView
         let hitView = super.hitTest(point, with: event)

         // If the hit view was ourself (meaning no subview was touched),
         // return nil instead. Otherwise, return hitView, which must be a subview.
         return hitView == self ? nil : hitView
     }
 }
  • Child1에서 Child2로 이동할 땐, ContainerVC의 자식을 remove 후 새로운 childVC를 add하는 방식
  • Coordinator 구성: ContainerCoordinator와 SubCoordianator존재
  • ContainerCoordinator에서 Sub로가는 로직 구현, Sub1, Sub2은 각 특색에 맞는 개별 Coordinator존재
  • Sub1, Sub2에서 ContainerVC에 접근하여 공통 로직을 처리(요청)하기 위해서 CommonHandlingDelegate라는 ,  delegate 추가
    - sub의 Dependencies에 Handling: MyContainerVC.viewModel로 넘김
    - sub에서 Container의 공통 로직을 이용할 땐 dependencies.handling.updateCount() 호출
    - sub에서 결과값을 얻을땐 CommonHandlingDelegate를 구현한 곳에서 얻음
    - delegate = self관련 로직은 Coordinator에서 subVC를 만든 후, containerVC.viewModel.delegate = vc.viewModel로 구현
// CommonHandling의 구현은 Container에서 - 데이터 처리 후 CommonHandlingDelegate로 넘겨줌
// CommonHandlingDelegate의 구현은 sub에서 - 데이터를 받기 위함

protocol CommonHandling {
    func updateCount()
}

protocol CommonHandlingDelegate: class {
    func didUpdateCount(info: String)
}

class MyContainerVM: ErrorHandleable {
    ...
    var myContainerDelegate: ComonHandleableDelegate?
}

...

extension MyContainerVM: CommonHandling {
    func updateCount() {
        myContainerDelegate.didUpdateCount(info: "업데이트 완료")
    }
}
  • Sub1VC, Sub2VC에서 View를 clear color로 설정 후 FloatingPanel프레임워크에 있는 PassThroughView로 설정하면 밑에 깔려있는ContainerVC와 interaction 가능(버튼 클릭 가능)

Comments