手动模态segue不起作用,View Controller不在窗口层次结构中?

时间:2013-03-25 04:47:17

标签: ios ios5 ios6 uistoryboard uistoryboardsegue

我一直在网上搜索和Stack Overflow几个小时,我无法解决这个问题。这里希望你们都看到我的错误,因为我找不到它。

我刚刚开始使用基于故事板的简单应用程序。最初的ViewController是UITabBarController的一个实例,它带有来自模板的两个虚拟ViewControllers。启动时,我需要检查设备是否已登录到外部服务。如果没有,我将展示一个允许用户进行身份验证的模态ViewController,如果设备已经过身份验证,那么我将只显示FirstViewController。

以下步骤是我创建项目后所做的一切:

  1. 在Storyboard上创建AuthenticateViewController场景
  2. 为AuthenticateViewController创建代码文件,并将它们分配给相应的场景
  3. 为UITabBarController子类创建代码文件,并将初始UITabBarController场景与该新子类关联
  4. 在故事板上从UITabBarController场景到AuthenticateViewController场景创建一个新的segue
  5. 从UITabBarController子类中的viewDidLoad手动调用segue
  6. 当我运行应用程序时,模态segue不会触发,显示UITabBarController的第一个ViewController,我在XCode中得到以下输出:

    Warning: Attempt to present <AuthenticateViewController: 0x83c0c10> on <EPTabBarController: 0x83be600> whose view is not in the window hierarchy!
    

    下面的相关代码,实际上是我到目前为止添加的唯一代码。如果截图或其他信息有用,请告诉我。在此先感谢您的帮助。

    EPTabBarController,UITabBarController的子类:

    #import "EPTabBarController.h"
    #import "AuthenticateViewController.h"
    
    @interface EPTabBarController ()
    
    @end
    
    @implementation EPTabBarController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        [self performSegueWithIdentifier:@"authenticationSegue" sender:self];
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    

3 个答案:

答案 0 :(得分:14)

问题出在

- (void)viewDidLoad
{
    [super viewDidLoad];    
    [self performSegueWithIdentifier:@"authenticationSegue" sender:self];
}

当您的当前视图(AuthenticateViewController)尚未加载到窗口层次结构中时,您试图呈现另一个视图(EPTabBarController)。

首先让您的EPTabBarController加载到窗口层次结构中,然后显示AuthenticateViewController

试一试

- (void)viewDidLoad 
{
    [super viewDidLoad];        
    [self performSelector:@selector(loadAuthenticateViewController) 
               withObject:nil 
               afterDelay:1.0];
}

-(void)loadAuthenticateViewController 
{
    [self performSegueWithIdentifier:@"authenticationSegue" sender:self];
}

答案 1 :(得分:3)

如何在viewDidAppear中调用代码呢?

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

然而,我仍然不满意这些解决方案,因为原始视图仍然显示不到一秒钟。

关于如何在不首先显示原始视图的情况下显示新模态的任何想法?

答案 2 :(得分:2)

当你真的想控制时,请使用以下内容:

@implementation UeInitialisationViewController
BOOL didLoad;
BOOL wantPush;

- (id)init {
    self = [super init];
    if (self) { didLoad = NO; wantPush = NO; }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    didLoad = YES;
    if (wantPush == YES)
        [self performSelector:@selector(pushToMainView) 
                   withObject:nil afterDelay:0.0001];
}

- (void)pushToMainView {
    if (didLoad == YES)
        [self performSegueWithIdentifier:@"pushToMainView" sender:self];
    else
        wantPush = YES;
}
@end

当您向pushToMainView发送消息时,这将触发Segue [controller pushToMainView]但会保留,直到视图加载为止。