设置 keyWindow rootViewController 在 iOS8 中不起作用

Setting the keyWindow rootViewController not working in iOS8

在我的应用程序中,我需要用户登录和注销。当我希望用户注销时,我会删除他们的凭据,然后:

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

假设用登录 viewController 替换当前的 rootViewController (tabBarController)。

在 iOS7 这可以正常工作。但是,在 iOS8 中它会显示登录 VC 瞬间,然后 return 返回到 tabBarController 就像什么都没发生一样。

对正在发生的事情有什么想法吗?

实际上这是一个与 iOS 8.In iOS 相关的问题 8 他们将在设置 rootViewController 属性 后保留旧的视图层次结构window also.So 我的解决方案是在设置新 rootviewcontroller.

之前删除子视图

Apple 文档也说,"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];
}

我遇到了完全相同的问题,登录 VC 将显示一瞬间,然后 return 返回到我的 SplitViewController,只有 iOS8、iOS7 可以正常工作很好。

在我的场景中,只有当我在注销前显示 AlertView 时才会发生这种情况,如果我在没有 AlertView 的情况下直接更改 rootViewController,它工作正常。

所以我用这个简单的解决方法修复了它:

- (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];
...

我的猜测是,在iOS8中,OS使用Window或rootViewController来设置和删除AlertView,存储对rootViewController的引用,然后将其设置回rootViewController解除 AlertView 后的引用。因此,如果您在 OS 将其设置回来之前更改 rootViewController,它将替换您的更改。如果您等待半秒直到 OS 完成对 rootViewController 的更改,问题就解决了。当然是假设。

我也遇到了这个问题。这是 AlertView 的问题。您可以使用 AlertView 的另一个名为 :alertView:didDismissWithButtonIndex: 的委托方法,在此方法中调用您的 Setting RootViewController.

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