简体   繁体   中英

Presenting a specific view controller from AppDelegate

I am trying to present a view controller (a passcode request type view) every time my app becomes active. Once the correct passcode is entered, it should pop off the stack. The passcode view I'm trying to push isn't the initial view controller, so I'm having trouble accessing it from the AppDelegate's applicationDidBecomeActive.

I also tried pushing the passcode view from my MainViewController's ViewWillAppear, but it doesn't get called when the app becomes active; only when the screen is refreshed.

I've been researching similar problems across SO the past couple days, but I'm still not understanding the proper method. I've heard that I might not be able to push the view this way because the applicationDidBecomeActive may be called before the Storyboard or NavigationController is connected/initialized/etc.

If anyone could provide me with the correct way to push/present the view, or if there's somewhere else that'd be better to do this type of thing, I'd appreciate it.

Solved : I just deleted the view from storyboard and used a nib instead. I used:

PasscodeUnlockVC *passcodeUnlock = [[PasscodeUnlockVC alloc] initWithNibName:@"PasscodeUnlockVC" bundle:[NSBundle mainBundle]];
[(UINavigationController *)self.window.rootViewController pushViewController:passcodeUnlock animated:NO];

View hierarchy data:

(gdb) po [[(id)UIApp keyWindow] recursiveDescription]
<UIWindow: 0x736a4b0; frame = (0 0; 320 480); layer = <UIWindowLayer: 0x7367b40>>
   | <UILayoutContainerView: 0x76977a0; frame = (0 0; 320 480); autoresize = W+H; layer =     <CALayer: 0x769de60>>
   |    | <UINavigationTransitionView: 0x7692110; frame = (0 0; 320 480); clipsToBounds = YES;      autoresize = W+H; layer = <CALayer: 0x769a8c0>>
   |    |    | <UIViewControllerWrapperView: 0x73868d0; frame = (0 64; 320 416); autoresize =  W+H; layer = <CALayer: 0x75510e0>>
   |    |    |    | <UIView: 0x76b93e0; frame = (0 0; 320 416); autoresize = W+H; layer = <CALayer: 0x7386850>>
   |    | <UINavigationBar: 0x73664b0; frame = (0 20; 320 44); clipsToBounds = YES; opaque =  NO; autoresize = W; layer = <CALayer: 0x7366550>>
   |    |    | <UINavigationBarBackground: 0x7360ea0; frame = (0 0; 320 44); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7366520>> - (null)
   |    |    | <UINavigationItemView: 0x76b95e0; frame = (160 21; 0 0); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x76aa8e0>>
   |    |    | <UINavigationItemButtonView: 0x7550650; frame = (5 7; 73 30); opaque = NO;   userInteractionEnabled = NO; layer = <CALayer: 0x7368b40>>
Current language:  auto; currently objective-c
(gdb) 

I suggest you use applicationWillEnterForeground: , not applicationDidBecomeActive: , because it works better with multitasking gestures. For example, you don't want to put up the lock screen if the user double-clicks the home button to display the task bar, and then dismisses the task bar without changing apps.

Presumably your AppDelegate has a window property, and you know that your window's root view controller is a UINavigationController .

- (void)applicationWillEnterForeground:(UIApplication *)application {
    PasscodeViewController *pvc = [[PasscodeViewController alloc] init];
    [(UINavigationController *)self.window.rootViewController pushViewController:pvc animated:NO];
    // [pvc release]; if not using ARC
}

Solved

PasscodeViewController *vc = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"passcodeVCID"]; 
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:vc];
navController.navigationBar.hidden = YES;
vc.mode = @"enable";
self.window.rootViewController = navController;  

Using in applicationWillEnterForeground method.

Swift version of Quick and generalised way:

getRootViewController().presentViewController(messageVC, animated: true, completion: nil)

func getRootViewController() -> UIViewController
{
    return (UIApplication.sharedApplication().delegate?.window??.rootViewController)!
}

Here is complete Solution in Swift 4 implement this in didFinishLaunchingWithOptions

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

 let isLogin = UserDefaults.standard.bool(forKey: "Islogin")
    if isLogin{
        self.NextViewController(storybordid: "OtherViewController")


    }else{
        self.NextViewController(storybordid: "LoginViewController")

    }
}

write this Function any where inside Appdelegate.swift

  func NextViewController(storybordid:String)
{

    let storyBoard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let exampleVC = storyBoard.instantiateViewController(withIdentifier:storybordid )
   // self.present(exampleVC, animated: true)
    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = exampleVC
    self.window?.makeKeyAndVisible()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM