AppDelegate, rootViewController and presentViewController

3 浏览
0 Comments

AppDelegate, rootViewController and presentViewController

我正在进行Facebook集成教程,如果用户具有当前状态的有效令牌,我想显示我的MainViewViewController,否则我想显示LoginViewController。

MainViewAppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
        // 待办事项,显示已登录视图
    } else {
        // 否则,显示登录页面。
        [self showLoginView];
    }
    return YES;
}
- (void)showLoginView
{
    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    LoginViewController *loginViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
    [self.window.rootViewController presentViewController:loginViewController animated:YES completion:NULL];
}

控制台错误:

警告:试图在不在窗口层次结构中的上呈现

我不想使用导航控制器。

0
0 Comments

问题的出现原因:在AppDelegate中使用presentViewController:animated:completion:方法时,可能会遇到无法显示模态视图控制器的问题。

解决方法:在调用presentViewController:animated:completion:方法之前,添加[self.window makeKeyAndVisible]方法,以确保窗口处于活动状态。

具体解决方法如下:

- (void)showLoginView

{

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

LoginViewController *loginViewController = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];

[self.window makeKeyAndVisible];

[self.window.rootViewController presentViewController:loginViewController animated:YES completion:NULL];

}

这个方法通过先调用makeKeyAndVisible方法,确保窗口处于活动状态,然后再调用presentViewController:animated:completion:方法来显示模态视图控制器。

通过以上方法,可以解决在AppDelegate中显示模态视图控制器的问题。这个解决方法对于一些遇到无法显示模态视图控制器的开发者来说非常有用,可以帮助他们节省时间和精力。感谢提供解决方法的开发者,让我们能够更好地理解和解决这个问题。

0
0 Comments

有时,从window.rootViewController中呈现模态视图控制器可能会产生相同的警告并且没有效果。

这种视图控制器层级结构的示例如下:

1. [MYUITableViewController](由MYUIViewController模态呈现)

2. [MYUIViewController](下面是UINavigationController的rootViewController)

3. [UINavigationController](根)

现在调用

[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:[UIViewController new] animated:YES completion:nil];

将导致此警告(在iOS6和7模拟器上测试过)。

解决方法:

不要使用rootViewController,而是使用由其呈现的顶部视图控制器:

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

while (topRootViewController.presentedViewController)

{

topRootViewController = topRootViewController.presentedViewController;

}

[topRootViewController presentViewController:yourController animated:YES completion:nil];

有时keyWindow可能已被具有nil rootViewController的窗口替换(在iPhone上显示UIAlertViews,UIActionSheets等),在这种情况下,您应该使用UIView的window属性。

我遇到了“对的不平衡的begin/end appearance transitions调用”错误。

伙计们,请帮个忙,我遇到了同样的问题,但是无法弄清楚Swift版本会是什么?我这样做:

var sharedApplicationVC: UIViewController! = self.window?.rootViewController

while var vvc = sharedApplicationVC.presentedViewController{

sharedApplicationVC = vvc

}

sharedApplicationVC.presentViewController(closeableVC, animated: true, completion: nil)

但是它给我一个内存泄漏问题:<UIKit/UIView.h>可能也有帮助。意外地在解包Optional值时找到nil致命错误。

如果屏幕上显示了UIAlertController并且想要呈现另一个视图控制器,这个方法是否有效?

谢谢!:) 你救了我的一天 🙂

是的!我尝试了所有方法,但都没有效果。这对我来说是正确的答案。救了我的一天!谢谢。

0
0 Comments

在这个问题中,出现的原因是需要在AppDelegate中处理不同的URL schemes以打开不同部分的应用程序。在AppDelegate的application(_:open:options:)方法中,可以检查URL的字符串形式,然后决定是否执行上面提到的代码或者使用不同的标识符(withIdentifier)执行类似的代码。

解决方法是使用下面提供的代码片段,其中包括了通过Storyboard实例化视图控制器以及查找最顶层的视图控制器并将其作为presentingViewController来呈现新的视图控制器。

let sb = UIStoryboard(name: "Main", bundle: nil)

let vc = sb.instantiateViewController(withIdentifier: "MainApp") as! ViewController

var topRootViewController: UIViewController = (UIApplication.shared.keyWindow?.rootViewController)!

while((topRootViewController.presentedViewController) != nil){

topRootViewController = topRootViewController.presentedViewController!

}

topRootViewController.present(vc, animated: true, completion: nil)

以上代码中的"MainApp"是主视图控制器的标识符。

为什么使用while而不是简单的if?因为使用while循环可以确保找到最顶层的视图控制器,而不仅仅是当前显示的视图控制器。

0