AppDelegate中,RootViewController的和presentViewContro

2019-06-21 04:48发布

我做的是Facebook的整合教程中,我想表明我MainViewViewController如果用户对当前的状态,否则我要显示LoginViewController有效令牌。

MainViewAppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
        // To-do, show logged in view
    } else {
        // No, display the login page.
        [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];
}

控制台错误:

Warning: Attempt to present <LoginViewController: 0xb492fd0> on <MainViewViewController: 0xb1bd820> whose view is not in the window hierarchy!

我不想使用NavigationController。

Answer 1:

我遇到过同样的问题。 基于回答这个问题 ,我添加[self.window makeKeyAndVisible]之前presentViewController:animated:completion: ,并固定为我。

在你的情况,showLoginView变

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


Answer 2:

有时从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可能已被取代窗口无RootViewController的(显示UIAlertViews,对iPhone等UIActionSheets),在这种情况下,你应该使用的UIView的窗口属性。


Answer 3:

斯捷潘Generalov的回答是斯威夫特3右一为我!
当然,随着新的语法等等,所以我会在这里复制:

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”是我的主视图控制器在这种情况下标识符。

我知道还有其他方法,但如果你需要有不同的URL方案打开你的应用程序的不同部分,你必须处理它的AppDelegate所以这是完美的,因为在

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {}

方法,可以只检查什么url是作为字符串,然后如果执行以上书面代码,或者一个类似的一个具有不同的标识符用于其它视图控制器决定( withIdentifier



Answer 4:

在斯威夫特3: -

let storyboard = UIStoryboard(name: "Login", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "LoginViewController")
window?.makeKeyAndVisible()
window?.rootViewController?.present(viewController, animated: true, completion: nil)


Answer 5:

在情况下,当你不使用故事板。 首先,你需要创建YourViewController。 转到文件 - >新建 - >文件...(或快捷方式 - 命令+ N)

在此之后,选择可可触摸类。 单击下一步,或Enter

比你的viewController,然后单击下一步类型名称

#import "AppDelegate.h"
#import "YourViewController.h"

@interface AppDelegate ()

@end

@implementaion AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// Init window
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
[self.window makeKeyAndVisible];

// Init YourViewController
YourViewController *viewController = [[YourViewController alloc] init];

// Init YourNavigationController
UINavigationController *navigationContoller = [[UINavigationController alloc] initWithRootViewController: viewController];

// Set rootViewController
self.window.rootViewController = navigationContoller;

return YES;

}

@end

斯威夫特3/4例

import UIKit

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

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

//1-st step
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()

//2-nd - create a window root controller, and create a layout
let layout = UICollectionViewFlowLayout()
window?.rootViewController = UINavigationController(rootViewController: HomeController(collectionViewLayout: layout))

return true

}



文章来源: AppDelegate, rootViewController and presentViewController