Skip to content

Instantly share code, notes, and snippets.

@TuenTuenna
Last active November 3, 2022 11:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save TuenTuenna/696cc8e0966eb2be64cac340aaea8904 to your computer and use it in GitHub Desktop.
Save TuenTuenna/696cc8e0966eb2be64cac340aaea8904 to your computer and use it in GitHub Desktop.
UIkit 에서 재귀함수를 활용한 최상단 뷰컨트롤러 가져오기 입니다!

UIkit 에서 재귀함수를 활용한 최상단 뷰컨트롤러 가져오기 입니다!

// UIApplication 익스텐션
extension UIApplication {
    
    func topViewController() -> UIViewController? {
       // 애플리케이션 에서 키윈도우로 제일 아래 뷰컨트롤러를 찾고
       // 해당 뷰컨트롤러를 기점으로 최상단의 뷰컨트롤러를 찾아서 반환
        
        let scenes = UIApplication.shared.connectedScenes
        let windowScenes = scenes.first as? UIWindowScene
        return  windowScenes?.windows
                  .filter { $0.isKeyWindow }
                  .first?.rootViewController?
                  .topViewController()
    }
}

// UIViewController 익스텐션
extension UIViewController {
    func topViewController() -> UIViewController {
        // 프리젠트 방식의 뷰컨트롤러가 있다면
        if let presented = self.presentedViewController {
            // 해당 뷰컨트롤러에서 재귀 (자기 자신의 메소드를 실행)
            return presented.topViewController()
        }
        // 자기 자신이 네비게이션 컨트롤러 라면
        if let navigation = self as? UINavigationController {
            // 네비게이션 컨트롤러에서 보이는 컨트롤러에서 재귀 (자기 자신의 메소드를 실행)
            return navigation.visibleViewController?.topViewController() ?? navigation
        }
        // 최상단이 탭바 컨트롤러 라면
        if let tab = self as? UITabBarController {
            // 선택된 뷰컨트롤러에서 재귀 (자기 자신의 메소드를 실행)
            return tab.selectedViewController?.topViewController() ?? tab
        }
        // 재귀를 타다가 최상단 뷰컨트롤러를 반환
        return self
    }
}

사용 예시

class SomeClass {
    // 이제 뷰컨트롤러가 아닌 클래스에서도 최상단 뷰컨트롤러를 찾을 수 있습니다
    func doSomethingWithTopVC(){
        guard let topVC = UIApplication.shared.topViewController() else { return }
        topVC.view.backgroundColor = .yellow
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment