手动模态segue不起作用,View Controller不在窗口层次结构中?
Posted
技术标签:
【中文标题】手动模态segue不起作用,View Controller不在窗口层次结构中?【英文标题】:Manual modal segue does not work, View Controller is not in the window hierarchy? 【发布时间】:2013-03-14 12:31:35 【问题描述】:我已经在网络和 Stack Overflow 上搜索了几个小时,但我无法解决这个问题。这里希望你们都看到我的错误,因为我找不到它。
我刚刚启动了一个基于故事板的简单应用程序。初始 ViewController 是 UITabBarController 的一个实例,其中包含模板中的两个虚拟 ViewController。启动时,我需要检查设备是否登录到外部服务。如果没有,我将显示一个允许用户进行身份验证的模态 ViewController,如果设备通过了身份验证,那么我将只显示 FirstViewController。
以下步骤是我创建项目后所做的一切:
-
在 Storyboard 上创建 AuthenticateViewController 场景
为AuthenticateViewController创建代码文件,并分配给对应的场景
为 UITabBarController 子类创建代码文件,并将初始 UITabBarController 场景与该新子类相关联
在情节提要上创建一个从 UITabBarController 场景到 AuthenticateViewController 场景的新转场
从 UITabBarController 子类中的
viewDidLoad
手动调用 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
【问题讨论】:
【参考方案1】:问题在里面
- (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];
【讨论】:
这可行,但让我觉得这是一个相当不雅的解决方案。这是实现这一目标的唯一方法吗? 'performSegueWithIdentifer:' 调用是否应该放在其他地方? 嘿@blundin 请尝试设置 afterDelay:0.0 并检查。让我知道工作是否顺利【参考方案2】:在 viewDidAppear 中简单地调用您的代码怎么样?
- (void)viewDidAppear
[super viewDidAppear];
[self performSegueWithIdentifier:@"authenticationSegue" sender:self];
但是,我仍然对这些解决方案不满意,因为原始视图仍会显示几分之一秒。
关于如何在不首先显示原始视图的情况下显示新模式的任何想法?
【讨论】:
【参考方案3】:当你真的想控制时,使用这样的东西:
@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
当您向 [controller pushToMainView]
发送消息时,这将触发 Segue pushToMainView
,但会阻止,直到加载视图。
【讨论】:
以上是关于手动模态segue不起作用,View Controller不在窗口层次结构中?的主要内容,如果未能解决你的问题,请参考以下文章
从 Unwind segue 触发时,Push segue 不起作用
Bootstrap V5 手动调用模态 myModal.show() 不起作用(香草 javascript)