직면한 상황

프로젝트를 하나 하는 도중에 하나의 뷰 컨트롤러 하위의 뷰 안에, 세 가지 뷰 컨트롤러를 스위치하며 담고 싶었습니다.  

처음에는 아래에 링크되어 있는 영상을 보며 storyboard를 이용하여 이를 구현해보았으나, didSelectRowAt 함수가 호출될 때 싱글턴 객체에 변수를 담고난 이후 viewController가 instantiate되어야 하는데 어떠한 방법의 비동기 처리를 해도 이것이 되지 않아 이를 코드로 구현하여 viewDidLoad 이후에 instantiate하도록 바꾸었습니다. (참고로 저와 같은 특수한 상황이 아니라면 아래 링크된 영상을 따르는 것도 잘 작동합니다.)

링크: https://www.youtube.com/watch?v=A6vxDDAUj2o&t=317s 

 

코드로 ContainerView 구현하기.

혹시나 저와 같은 분들이 계실까봐 기록을 남깁니다.

일단 다음과 같은 viewController에서 세 가지 옵션을 가진 segmentedControl의 값이 변경될 때마다 특정 view를 보여주려고 합니다.

 

이러한 상황에서 세 가지 ViewController의 storyboardID를 각각 PhotosVC, ReviewVC, DetailMapVC라고 해봅시다.

예시

 

그리고 segmentedControl을 연결하고 세 가지 변수를 선언해줍시다. 

각각의 uiview들은 우리가 나중에 연결해줄 viewController의 root view가 됩니다.

class DetailViewController: UIViewController {

    @IBOutlet weak var segmentedControl: UISegmentedControl!
    
    var photosView: UIView!
    var reviewsView: UIView!
    var mapView: UIView!

 

이제 viewDidLoad 시점에 다음 함수를 호출해줍니다.

 override func viewDidLoad() {
        super.viewDidLoad()

        instantiateSegmentedViewControllers()
 }

 

해당 함수는 

1. storyboard에서 우리가 보여줄 ViewController를 초기화하고,

2. self.view에 그것들을 add해준 뒤,

3. constriants를 설정해줄 것입니다.

그게 답니다.

 

구체적인 코드는 다음과 같습니다.

// segmentedControl과 연결된 ViewController들을 초기화하고,
    // 해당 view들을 현재(self) view에 추가한다.
    private func instantiateSegmentedViewControllers() {
        guard let photosVC = self.storyboard?.instantiateViewController(withIdentifier: "PhotosVC"),
              let reviewsVC = self.storyboard?.instantiateViewController(withIdentifier: "ReviewVC"),
              let detailMapVC = self.storyboard?.instantiateViewController(withIdentifier: "DetailMapVC")
        else { fatalError("can't find PhotosVC") }
        
        self.addChild(photosVC)
        self.addChild(reviewsVC)
        self.addChild(detailMapVC)
        photosVC.view.translatesAutoresizingMaskIntoConstraints = false
        reviewsVC.view.translatesAutoresizingMaskIntoConstraints = false
        detailMapVC.view.translatesAutoresizingMaskIntoConstraints = false
        
        self.view.addSubview(reviewsVC.view)
        self.view.addSubview(detailMapVC.view)
        self.view.addSubview(photosVC.view)
        
        NSLayoutConstraint.activate([
            photosVC.view.topAnchor.constraint(equalTo: self.segmentedControl.bottomAnchor, constant: 10),
            photosVC.view.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0),
            photosVC.view.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0),
            photosVC.view.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0),
            
            reviewsVC.view.topAnchor.constraint(equalTo: self.segmentedControl.bottomAnchor, constant: 10),
            reviewsVC.view.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0),
            reviewsVC.view.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0),
            reviewsVC.view.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0),
            
            detailMapVC.view.topAnchor.constraint(equalTo: self.segmentedControl.bottomAnchor, constant: 10),
            detailMapVC.view.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0),
            detailMapVC.view.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0),
            detailMapVC.view.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0)
            
        ])
        
        
        self.photosView = photosVC.view
        self.reviewsView = reviewsVC.view
        self.mapView = detailMapVC.view
        
        
    }

 

여기까지 따라했다면 마지막으로 segmentedControl과 연결되는 @IBAction func 하나를 생성해줍니다.

이름은 switchViews 정도로 하겠습니다.

그리고 해당 함수의 내용은 다음과 같이 합니다.

isHidden 함수를 쓰지 않는 이유는 isHidden 함수를 사용하는 경우 animation을 적용하지 않기 때문입니다. 다른 이유는 없습니다.

    @IBAction func switchViews(_ sender: UISegmentedControl) {
        if sender.selectedSegmentIndex == 0 {
            photosView.alpha = 1
            reviewsView.alpha = 0
            mapView.alpha = 0
        } else if sender.selectedSegmentIndex == 1 {
            photosView.alpha = 0
            reviewsView.alpha = 1
            mapView.alpha = 0
        } else {
            photosView.alpha = 0
            reviewsView.alpha = 0
            mapView.alpha = 1
        }
        
    }

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기
// custom