简体   繁体   中英

Setting the keyWindow rootViewController not working in iOS8

In my app I need the user to login and logout. When I want the user to logout, I delete their credentials and then:

ZSSLogin *login = [self.storyboard instantiateViewControllerWithIdentifier:@"ZSSLogin"];
[[UIApplication sharedApplication].keyWindow setRootViewController:[[UINavigationController alloc] initWithRootViewController:login]];

Which is suppose to replace the current rootViewController (tabBarController) with the login viewController .

On iOS7 this works correctly. But, in iOS8 it will show the login VC for a split second, but then return back to the tabBarController like nothing happened.

Any ideas on what is going on?

I had the exactly same problem, login VC will show for a split second and then return back to my SplitViewController and only iOS8, iOS7 was working fine.

On my scenario, this happened only whenever I presented an AlertView before the log out, if I went straight into changing the rootViewController without AlertView it worked fine.

So I fixed it with this simple workaround:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
...

    // Added a delay to avoid an iOS8 bug, where setting rootViewControler doesn't work after dismissing an AlertView. (For some reason dispatch_after isn't working here)
    [self performSelector:@selector(logout) withObject:nil afterDelay:0.5];
...

My guess is that in iOS8, OS uses Window or rootViewController to set and remove the AlertView, stores a reference to the rootViewController and then set it back the rootViewController to that reference after dismissing the AlertView. So if you change the rootViewController before the OS sets it back, it will replace you change. If you wait half a second till the OS finishes making changes to the rootViewController, the problem is solved. Of Course, is a supposition.

I got this problem too. This is something wrong with AlertView. You can use AlertView's another Delegate method named : alertView:didDismissWithButtonIndex: In this method call your Setting RootViewController .

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    if(buttonIndex == 0){
        // change Application.keyWindow.rootViewController
    }
}

Actually this is an issue related to iOS 8.In iOS 8 they will keep the old view hierarchy after setting the rootViewController property of the window also.So my solution is that remove the sub views before setting the new rootviewcontroller .

Apple docs also saying, "The root view controller provides the content view of the window. Assigning a view controller to this property (either programmatically or using Interface Builder) installs the view controller's view as the content view of the window. If the window has an existing view hierarchy, the old views are removed before the new ones are installed."

for (UIView * subView in self.window.rootViewController.view.subviews) {
    [subView removeFromSuperview];
}

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