본문 바로가기

UIKit

[UIKit] 특정 ViewController 가 띄워져 있음을 감지하는 방법

이번 주제는

개발을 진행할때 마주한 문제를 해결했던 방법에 대해

설명해볼까합니다.

 

func presentViewController() {
        let childViewController = ChildViewController()
        childViewController.modalPresentationStyle = .fullScreen
        present(childViewController, animated: true, completion: nil)
    }

 

문제 상황은 A ViewController (parent) 에서 

ChildViewController 를 present 방식으로 띄우는데

전역변수가 아닌 지역변수로 설정을 해둔 상태이고,

 

A ViewController 의 다른 메서드에서 

ChildViewController 가 present 되었는지를 체크해야하는 상황이였습니다.

 

전역변수로 설정이 되어있다면

존재 유무를 금방 알 수 있었을 텐데

지역변수로 설정되어 있다보니 금방 확인하기엔 문제가 있었습니다.

 

이 문제를 해결하기 위해 제가 확인한 것은 

UIViewController 가 제공하는 presentedViewController 프로퍼티였습니다.

presentedViewController 프로퍼티는

현재 ViewController 가 present 한 ViewController 를 의미하게 됩니다.

추가적으로 알아두셔야 할 것은

presentedViewController 가 반환하는 값은 가장 상위의 ViewController 라는 점 입니다!

 

가장 상위에 올라와 있는 ViewController 를 확인하고

인스턴스의 실제 타입을 체크하기 위해 is 연산자를 사용해주면 다음과 같은

코드를 작성할 수 있습니다.

 

extension UIViewController {
    func isChildViewControllerPresented(_ viewControllerType: UIViewController.Type) -> Bool {
        if let presentedVC = self.presentedViewController, presentedVC is ChildViewController {
            return true
        }
        return false
    }
}

 

위와 같은 코드를 UIViewController 의 extension 으로 추가해주고

사용한다면 문제 상황을 해결하실 수 있을 겁니다.

 

추가적으로 저의 경우 is 연산자를 사용하여 확인하는 것이 아닌

type(of:) 를 사용하여 검사를 진행하려했는데

type(of:) 의 경우 정확히 일치하는 타입일 경우만 체크할 수 있다고 합니다!

특정 타입이나 서브타입까지 체크해주는 것은 is 연산자라고 하니

이번 기회에 다시 한번 체크해보는 것도 좋을듯합니다.

 

특징 type(of:) is
목적 정확한 타입 확인 특정 타입 or 서브 타입 여부 확인
결과 정확히 일치하는 타입만 반환 타입 또는 상위 클래스와의 일치 여부 반환
상위 클래스 포함 여부 포함 X 포함 O (상위클래스 or 프로토콜도 체크)
사용예시 type(of: instance) == SomeType.self istance is SomeType

 

전체 코드는 아래 남겨둘테니 필요하신분은 참고 부탁드립니다!

 

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        presentViewController()
    }
    
    func presentViewController() {
        let childViewController = ChildViewController()
        childViewController.modalPresentationStyle = .fullScreen
        present(childViewController, animated: true) {
            if self.isChildViewControllerPresented(ChildViewController.self) {
                print("자식 뷰가 존재합니다!")
            } else {
                print("자식 뷰가 존재하지 않습니다")
            }
        }
    }
}

class ChildViewController: UIViewController {
    
    override func viewDidLoad() {
        view.backgroundColor = .red
        if view.frame == .zero {
            view.frame = UIScreen.main.bounds
        }
    }
}