在ViewDidLoad上执行Segue

ada*_*101 56 ios ios5 uistoryboard

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

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

Sco*_*ood 47

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

- (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];
}
Run Code Online (Sandbox Code Playgroud)

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

  • 解决方案有效 但是这种方法在跳过之前会显示另一个屏幕.有没有办法避免这种情况? (24认同)
  • 将它放在viewDidAppear中似乎会导致底层视图的短暂闪烁,即使动画:NO设置也是如此.关于如何防止任何闪光的任何想法? (10认同)
  • 如果将视图控制器的基本视图设置为隐藏,则会获得闪光但使用黑色背景而不是基础视图. (7认同)
  • 通过设置`vc.view.hidden = YES`可以避免闪光. (6认同)
  • 由于闪光灯,这似乎不是正确的解决方案. (3认同)

bea*_*ain 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;
}
Run Code Online (Sandbox Code Playgroud)


NJo*_*nes 22

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

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

[super viewDidAppear]调用之后,您有一个完全加载的视图进行修改.


Ela*_*son 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;
}
Run Code Online (Sandbox Code Playgroud)


Leo*_*zov 10

更新:此解决方案不再适用于iOS 8.

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

Apple的文档实际建议相同:

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

此解决方案的优点是它可以与主故事板加载机制一起使用,因此您无需手动加载任何内容并编写不必要的代码.

我在iOS 6.1,7.0和7.1上成功使用此解决方案,它也适用于iOS 5.

  • 对我来说,这似乎是最好的答案.没有闪光.没有处理窗口可见性.代码示例(或两个)会使答案更好. (3认同)

Sur*_*oza 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)
    }
}
Run Code Online (Sandbox Code Playgroud)


pba*_*ski 5

对于Swift:

dispatch_async(dispatch_get_main_queue()) {
   self.performSegueWithIdentifier("toView2", sender: self)
}
Run Code Online (Sandbox Code Playgroud)

对于Swift 3:

DispatchQueue.main.async {
    self.performSegueWithIdentifier("toView2", sender: self)
}
Run Code Online (Sandbox Code Playgroud)