루트 뷰 컨트롤러를 얻는 방법?


109

루트 뷰 컨트롤러의 인스턴스가 필요합니다.

나는 그 접근법을 시도했다.

UIViewController *rootViewController = (UIViewController*)[[[UIApplication sharedApplication] keyWindow] rootViewController];

반환 값 : null :

또한 컨트롤러 배열을 얻으려고 할 때 :

NSArray *viewControllers = self.navigationController.viewControllers;

하나의 컨트롤러 만 반환하지만 내 루트 뷰 컨트롤러가 아닙니다.

내비게이션 컨트롤러에서 가져 오려고하면 :

UIViewController *root = (UIViewController*)[self.navigationController.viewControllers objectAtIndex:0];

반환 값 : null :

이유는 무엇입니까? 루트 뷰 컨트롤러의 인스턴스를 얻기 위해 또 무엇을 시도 할 수 있습니까?

감사.


keyWindow는 활성화 된 창입니다. ] 더 나은.
无夜之星辰

답변:


213

rootViewControllerappDelegate에서 설정 한에 액세스하려는 경우 . 이 시도:

목표 -C

YourViewController *rootController = (YourViewController*)[[(YourAppDelegate*)
                                   [[UIApplication sharedApplication]delegate] window] rootViewController];

빠른

let appDelegate  = UIApplication.sharedApplication().delegate as AppDelegate
let viewController = appDelegate.window!.rootViewController as YourViewController

스위프트 3

let appDelegate  = UIApplication.shared.delegate as! AppDelegate
let viewController = appDelegate.window!.rootViewController as! YourViewController

Swift 4 및 4.2

let viewController = UIApplication.shared.keyWindow!.rootViewController as! YourViewController

Swift 5 및 5.1 및 5.2

let viewController = UIApplication.shared.windows.first!.rootViewController as! YourViewController

3
YourViewController * rootController = (YourViewController *) [[(YourAppDelegate *) [[UIApplication sharedApplication] delegate] window] rootViewController];
Craig Moore

1
Swift2에서는 "let appDelegate = UIApplication.sharedApplication (). delegate as! AppDelegate"를 사용하여 강제로 풀어야합니다
Jacky

두 컨트롤러를 이러한 방식으로 할당하여 두 컨트롤러에서 시계로 데이터를 가져올 수있는 방법이 있습니까?
Johnny Marin

1
이것은 생명의 은인입니다. 감사합니다! 이 맛있는 코드를 찾는 데 몇 달이 걸렸습니다!
ItsMeDom

37

목표 -C

UIViewController *controller = [UIApplication sharedApplication].keyWindow.rootViewController;

스위프트 2.0

let viewController = UIApplication.sharedApplication().keyWindow?.rootViewController

스위프트 5

let viewController = UIApplication.shared.keyWindow?.rootViewController

3
이것이 최고의 답변이어야합니다. +1 기본 앱이 종속 된 다른 프레임 워크에서 루트 뷰 컨트롤러를 참조해야하는 경우 다른 답변은 작동하지 않습니다.
C. Tewalt

10

제안으로 여기 @의 0x7fffffff에 의해 당신이 UINavigationController가있는 경우, 할 쉽게 할 수 있습니다 :

YourViewController *rootController =
    (YourViewController *)
        [self.navigationController.viewControllers objectAtIndex: 0];

위 답변의 코드는 UINavigation 컨트롤러 (있는 경우)를 반환하며 이것이 필요한 경우 self.navigationController.


5

정당한 이유가없는 한 루트 컨트롤러에서 다음을 수행하십시오.

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(onTheEvent:)
                                             name:@"ABCMyEvent"
                                           object:nil];

알림을 받으려는 경우 :

[[NSNotificationCenter defaultCenter] postNotificationName:@"ABCMyEvent"
                                                object:self];                

2

스위프트 3

let rootViewController = UIApplication.shared.keyWindow?.rootViewController

1

신속한 방법으로 어디에서나 호출 할 수 있으며 선택 사항을 반환하므로 조심하십시오.

/// EZSwiftExtensions - Gives you the VC on top so you can easily push your popups
var topMostVC: UIViewController? {
    var presentedVC = UIApplication.sharedApplication().keyWindow?.rootViewController
    while let pVC = presentedVC?.presentedViewController {
        presentedVC = pVC
    }

    if presentedVC == nil {
        print("EZSwiftExtensions Error: You don't have any views set. You may be calling them in viewDidLoad. Try viewDidAppear instead.")
    }
    return presentedVC
}

다음과 같은 표준 기능으로 포함됩니다.

https://github.com/goktugyil/EZSwiftExtensions


1

Swift 3 : Segue없이 ViewController를 변경하고 AnyObject 사용 : 대상 ViewController의 Identity MainPageViewController

let mainPage = self.storyboard?.instantiateViewController(withIdentifier: "MainPageViewController") as! MainPageViewController

var mainPageNav = UINavigationController(rootViewController: mainPage)

self.present(mainPageNav, animated: true, completion: nil)

또는 뷰 컨트롤러를 변경하고 데이터를 보내려는 경우

let mainPage = self.storyboard?.instantiateViewController(withIdentifier: "MainPageViewController") as! MainPageViewController

let dataToSend = "**Any String**" or  var ObjectToSend:**AnyObject** 

mainPage.getData = dataToSend 

var mainPageNav = UINavigationController(rootViewController: mainPage)

self.present(mainPageNav, animated: true, completion: nil)  

당신은 가장 좋은 친구 :
BSM-2000
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.