在ViewDidLoad上执行Segue
在iOS 5中,我有一个模板视图控制器的故事板,我想显示,如果它的用户的第一次在应用程序,之后,我想跳过这个视图控制器。
我设置了一个NSDefault键来处理这个,但是当我检查这个是否被设置,然后使用performSegueWithIdentifier来启动segue时,没有任何反应。 如果我把这个segue后面的button,它工作正常…
我回答了一个类似的问题,开发者想在开始时显示login屏幕。 我把他的一些示例代码放在一起,可以在这里下载。 解决这个问题的关键是在适当的时候调用事物,如果你想显示这个新的视图控制器,你会看到在这个例子中你必须使用这样的东西
- (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]; }
我也解释了在这里你可以看到如何工作和故事板
在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; }
问题是在完全添加第一个视图之前,您正在添加第二个视图。 尝试把你的代码放在:
-(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; // Present your modal from here }
在[super viewDidAppear]
被调用之后,你有一个完全加载的视图来修改。
在viewDidLoad中执行segges并没有什么主要问题(在调用super之后)。
问题是在应用程序的窗口可见之前执行segues。 您要显示的UIViewController是主要故事板的一部分,因此在应用程序开始在应用程序委托中运行代码之前将其加载到内存中。 在你的情况下,viewDidLoad在你的应用程序窗口得到消息之前由iOS调用: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; }
更新:此解决scheme不再适用于iOS 8。
解决你的问题的正确方法是在applicationDidBecomeActive:
app委托方法或UIApplicationDidBecomeActiveNotification
通知处理程序中触发segue / present模式视图控制器。
苹果的文档实际上也build议 :
如果您的应用程序之前位于后台,您也可以使用它来刷新应用程序的用户界面。
这个解决scheme的优点是它可以和主要的故事板加载机制一起工作,所以你不需要手动加载任何东西并写入不必要的代码。
我在iOS 6.1,7.0和7.1上成功使用这个解决scheme,它也可以在iOS 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) } }
对于Swift:
dispatch_async(dispatch_get_main_queue()) { self.performSegueWithIdentifier("toView2", sender: self) }
对于Swift 3:
DispatchQueue.main.async { self.performSegueWithIdentifier("toView2", sender: self) }
我有同样的问题。 在发现这个问题之前,我通过在主线程中使用async来解决这个问题。 这样,这个代码将在创build视图后立即由UI线程调用。
dispatch_async(dispatch_get_main_queue(), ^{ [self performSegueWithIdentifier:@"segueAlbums" sender:self]; });
这个代码可以在viewDidLoad
方法中调用。
更新了Swift 3
下面的代码片段允许你加载你想要的任何viewController。 在我的情况下,这是一个TabBarController如果用户有一个有效的Facebooklogin令牌。 与其他Swift 3解决scheme相比,这种解决scheme的优点是瞬间无屏幕闪烁。
func applicationDidBecomeActive(_ application: UIApplication) { if FBSDKAccessToken.current() != nil { self.window?.rootViewController?.present((self.window?.rootViewController?.storyboard?.instantiateViewController(withIdentifier: "TabBarController"))!, animated: false, completion: nil) } }
最好的解决办法是做到这一点:
-(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; [self performSegueWithIdentifier:@"NameSegue" sender:self]; }
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() } }