Skip to content

Latest commit

 

History

History
156 lines (127 loc) · 6.67 KB

README.md

File metadata and controls

156 lines (127 loc) · 6.67 KB

Sample Swift ContainerView

UIViewController 하위에 Container View를 이용하여 Controller를 작동(연결) 할 수 있습니다.
그것을 스토리보드와 코드를 이용해서 스크롤뷰 안에 들어가는 뷰들을 Container View로 넣어서 셈플링한 소스 입니다.
Container View 1,2는 스토리보드로,
Container View 3은 코드로 추가했습니다. 3은 제거하는 기능까지 테스트 했습니다.

주요 설명

License Swift 4

  • 스크롤뷰 안의 스크롤뷰의 내부 컨텐츠를 담는 뷰를 크게 만들고 그 안에 페이지 단위 View 들 안에 Container View 를 담았습니다.
  • 현재의 뷰 안에 컨트롤러를 연결 시킨 것과 다른 스토리보드의 파일을 링크 시킨 두가지 경우로 셈플링 하였습니다.

스토리보드 이미지

실행 이미지 (GIF)

실행 결과 계층 구조

  • Container View 1,2를 스토리보드로 추가한 계층

  • Container View 3을 버튼을 눌러 코드로 추가한 계층

결과 소스 및 파일

실제 받아서 실행해 보셔요~

  • Main.storyboard : 여기에 기본 베이스 화면을 구성했습니다.
  • Other.storyboard : 오른쪽의 두번째 Container View에 들어갈 RightViewController가 들어있습니다. (Container View 2)
  • ViewController.swift : 가로 길이가 디바이스에 따라 변하게 하였고, 스크롤뷰의 이벤트 받는 부분을 살짝 추가해봤습니다.
class ViewController: UIViewController {

    @IBOutlet weak var scrollViewContainerViewWidth: NSLayoutConstraint!
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Setting the ContainerView's width size for the ScrollView
        scrollViewContainerViewWidth.constant = UIScreen.main.bounds.size.width * 2
    }
    
    // addChildController
    @IBAction func onAddChildController(_ sender: Any) {
        let storyboard = UIStoryboard(name: "Other", bundle: nil)
        let addViewController = storyboard.instantiateViewController(withIdentifier: "AddViewController")
        // if Constraints
//        addViewController.view.translatesAutoresizingMaskIntoConstraints = false
        
        self.addChild(addViewController)
        self.view.addSubview(addViewController.view)
        
        // if Constraints
//        self.view.addConstraints(addViewController.view.constraints)
        
        addViewController.didMove(toParent: self)
    }
}

extension ViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print("Current X,Y are X:\(scrollView.contentOffset.x), Y: \(scrollView.contentOffset.y)")
        let currentPage = Int(round(scrollView.contentOffset.x / scrollView.frame.size.width))
        print("current page : \(currentPage)")
    }
}
  • LeftViewController.swift : 배경 컬러만 확인을 위해 수정했습니다.
    • StoryBoard로 추가한 케이스 입니다.
    • RightViewController.swift는 배경 색상만 달라서 별도 소스는 추가 안했습니다.
class LeftViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // TEST backgroundColor
        view.backgroundColor = #colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1)
    }
    
    // willMove -> It appears on the parent screen.
    override func willMove(toParent parent: UIViewController?) {
        print(#function)
        if let `parent` = parent as UIViewController? {
            print(parent)   // TestScrollViewAndContainerView.ViewController
        }
    }
    
    // It appears on the parent screen. -> didMove
    override func didMove(toParent parent: UIViewController?) {
        print(#function)
        if let `parent` = parent as UIViewController? {
            print(parent)
        }
    }
}
  • AddViewController.swift : 코드 레벨로 Contrainer View를 추가했습니다.
class AddViewController: UIViewController {
    deinit {
        // check remove self
        print(#function)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // TEST backgroundColor
        view.backgroundColor = #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1)
    }
    
    // willMove -> It appears on the parent screen.
    override func willMove(toParent parent: UIViewController?) {
        print(#function)
        if let `parent` = parent as UIViewController? {
            print(parent)
        }
    }
    
    // It appears on the parent screen. -> didMove
    override func didMove(toParent parent: UIViewController?) {
        print(#function)
        if let `parent` = parent as UIViewController? {
            print(parent)
        }
    }
    
    // remove child view controller
    @IBAction func onRemoveChildViewController(_ sender: Any) {
        // Notify the parent to remove it by calling willMove.
        // willMove 를 호출해서 제거한다는 것을 알립니다.
        self.willMove(toParent: nil)
        // Remove Constraint.
        // 제약사항 제거
        self.view.removeFromSuperview()
        // Remove the relationship of the child connected to the parent.
        // 부모에 연결된 자식의 관계를 제거합니다.
        self.removeFromParent()
    }
}

추가 설명

  • 단순하게 addSubView를 하면 부모자식관계는 성립하지 않습니다.
  • addChildViewController를 이용해서 자식 컨트롤러를 추가합니다.
  • 추가 완료된 이후에는 부모컨트롤러에서 didMove:를 호출해 줘야 합니다.
  • removeFromParentViewController를 이용해서 자식 컨트롤러를 제거합니다.
  • 제거 순서는 자식의 부모 뷰를 Container View 계층에서 제거한 후, 자식과 부모는 Container View Controller와 연결을 끊어야 합니다.
  • 자식 컨트롤러가 오토레이아웃 환경인 경우 translatesAutoresizingMaskIntoConstraints 설정도 신경씁니다.

링크