在ViewDidLoad上执行Segue

时间:2011-11-22 03:56:41

标签: ios ios5 uistoryboard

在iOS 5中,我有一个带有模态视图控制器的故事板,如果用户第一次在应用程序中,我想显示它,之后我想跳过这个视图控制器。

我设置了一个NSDefault键来处理这个问题,但是当我检查是否设置了它然后使用performSegueWithIdentifier来启动segue时,没有任何反应。如果我把这个segue放在一个按钮后面就可以了......

11 个答案:

答案 0 :(得分:47)

我回答了类似的问题,开发人员希望在开始时显示登录屏幕。我为他准备了一些示例代码,可以下载here。解决这个问题的关键是如果你想要显示这个新的视图控制器,在正确的时间调用东西,你会在示例中看到你必须使用这样的东西

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
    [vc setModalPresentationStyle:UIModalPresentationFullScreen];

    [self presentModalViewController:vc animated:YES];
}

我还解释了segues和storyboards如何工作,你可以看到here

答案 1 :(得分:42)

在ViewDidLoad中加载导致“底层”闪烁。我通过编程方式加载我的Storyboard解决了这个问题。因此,在Target / Main Storyboard下 - 留空。然后添加以下内容:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    // Load Main App Screen
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    HomeScreenVC *homeScreenVC = [storyboard instantiateInitialViewController];
    self.window.rootViewController = homeScreenVC;
    [self.window makeKeyAndVisible];

    // Load Login/Signup View Controller
    UIViewController *mainLoginVC = [storyboard instantiateViewControllerWithIdentifier:@"MainLoginVC"];
    [mainLoginVC setModalPresentationStyle:UIModalPresentationFullScreen];
    [homeScreenVC presentModalViewController:mainLoginVC animated:NO];

    return YES;
}

答案 2 :(得分:22)

问题是您是在完全添加第一个视图之前向层次结构添加第二个视图。尝试将代码放入:

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    // Present your modal from here
}

调用[super viewDidAppear]后,您将拥有一个完整加载的视图进行修改。

答案 3 :(得分:11)

在viewDidLoad中执行segue没有任何主要问题(当然在调用super之后)。

问题是在应用程序窗口可见之前执行segues。 您想要显示的UIViewController是主故事板的一部分,因此在应用程序开始在应用程序委托中运行它的代码之前将其加载到内存中。在您的情况下,在应用程序窗口收到消息之前,iOS会调用viewDidLoad:MakeKeyAndVisible。

重要的部分是能见度。 在窗口不可见的视图层次结构上执行segue无效!

您可以尝试这样做:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// The window initialized with hidden = YES, so in order to perform the segue we need to set this value to NO.
// After this action, the OS will add the window.rootViewController's view as a subview of the window.
self.window.hidden = NO;

[self.window.rootViewController performSegueWithIdentifier:_IDENTIFIER_ sender:self.window.rootViewController];

// Now that the window is not hidden, we must make it key.
[self.window makeKeyWindow];
return YES;
}

答案 4 :(得分:10)

更新:此解决方案在iOS 8中不再有效。

解决问题的正确方法是在applicationDidBecomeActive: app delegate方法或UIApplicationDidBecomeActiveNotification通知处理程序中触发segue / present模态视图控制器。

Apple的文档实际上advises the same

  

如果您的应用之前位于后台,您还可以使用它来刷新应用的用户界面。

此解决方案的优势在于它可与主故事板加载机制配合使用,因此您无需手动加载任何内容并编写不必要的代码。

我在iOS 6.1,7.0和7.1上成功使用此解决方案,它也可以在iOS 5上运行。

答案 5 :(得分:5)

这就是我在SWIFT中的表现。这也隐藏了视图控制器。

override func viewWillAppear(animated: Bool) {
    let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()

    let isloggedIn = prefs.objectForKey("isLoggedIn") as? Bool
    if (isloggedIn != false) {
        self.view.hidden = true
    } else {
        self.view.hidden = false
    }
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(true)

    let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()

    let isloggedIn = prefs.objectForKey("isLoggedIn") as? Bool
    if (isloggedIn != false) {
        println("this should work")
        self.performSegueWithIdentifier("Login", sender: self)
    }
}

答案 6 :(得分:2)

Swift 3

override func viewWillAppear(_ animated: Bool) {
    if authPreference.isExist() == true {
        self.view.isHidden = true
    } else {
        self.view.isHidden = false
    }
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(true)

    if authPreference.isExist() == true {
        navigateToSegue()
    }
}

答案 7 :(得分:1)

我遇到了同样的问题。在找到这个问题之前,我通过在主线程中使用async解决了这个问题。这样,在创建视图后,UI线程将立即调用此代码。

dispatch_async(dispatch_get_main_queue(), ^{
        [self performSegueWithIdentifier:@"segueAlbums" sender:self];
    });

可以在viewDidLoad方法中调用此代码。

答案 8 :(得分:1)

针对Swift 3进行了更新

下面的代码片段允许您加载所需的viewController。在我的情况下,如果用户有一个有效的Facebook登录令牌,它是一个TabBarController。与其他Swift 3解决方案相比,这个解决方案的好处是它可以瞬间完成,没有屏幕闪烁。

func applicationDidBecomeActive(_ application: UIApplication) {
    if FBSDKAccessToken.current() != nil {
        self.window?.rootViewController?.present((self.window?.rootViewController?.storyboard?.instantiateViewController(withIdentifier: "TabBarController"))!, animated: false, completion: nil)           
    }
}

答案 9 :(得分:0)

最好的解决方案是:

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];    
    [self performSegueWithIdentifier:@"NameSegue" sender:self];
}

答案 10 :(得分:0)

我为{3}改编了@bearMountain answer

func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    window = UIWindow(frame: UIScreen.main.bounds)
    let yourInitialVC: UIViewController? = storyboard.instantiateViewController(withIdentifier: "TermsVC")
    window?.rootViewController = termsVC
    window?.makeKeyAndVisible()
    return true
}