Ios 使用导航控制器时如何跳过2个视图
在Xcode 5.0.2中,我创建了一个iPhone应用程序(完整的应用程序,请运行Ios 使用导航控制器时如何跳过2个视图,ios,iphone,objective-c,uinavigationcontroller,Ios,Iphone,Objective C,Uinavigationcontroller,在Xcode 5.0.2中,我创建了一个iPhone应用程序(完整的应用程序,请运行pod install一次,用于SDWebImage),它显示社交网络列表(Facebook、Google+等),然后在另一个视图中显示一个UIWebView显示OAuth2网页,然后是第三个显示用户头像和详细信息的视图(名、姓等): (如上图所示) 在最后一个视图中显示用户化身和详细信息之前,我将用户数据保存到NSUserDefaults 我的问题是:当用户下次启动应用程序时,并且NSUserDefault
pod install
一次,用于SDWebImage
),它显示社交网络列表(Facebook、Google+等),然后在另一个视图中显示一个UIWebView
显示OAuth2网页,然后是第三个显示用户头像和详细信息的视图(名、姓等):
(如上图所示)
在最后一个视图中显示用户化身和详细信息之前,我将用户数据保存到NSUserDefaults
我的问题是:当用户下次启动应用程序时,并且NSUserDefaults
中已经有用户数据-我如何跳过前两个视图并显示(没有任何动画)带有这些用户详细信息的最后一个视图
我已将以下代码添加到
可以看到,用户数据正在加载,但我不知道如何跳转到最后一个视图(特别是因为大部分UI都是在脚本中定义的)
更新:我已尝试按照Tommy Alexander的建议(谢谢!)在中使用以下代码(并将详细信息故事板ID分配到最后一个视图):
虽然最后一个视图(带有用户头像和详细信息)似乎已实例化,但我收到以下警告,并且应用程序不会跳转到最后一个视图:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *key = [defaults objectForKey:@"key"];
User *user = [User loadForKey:key];
if (user) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *uvc = [storyboard instantiateViewControllerWithIdentifier:@"Details"];
NSLog(@"XXX uvc=%@ user=%@", uvc, user);
[self.window.rootViewController presentViewController:uvc animated:YES completion:nil];
}
return YES;
}
MyAuth[3917:70b] XXX uvc=<UserViewController: 0x8acbac0> user=
VK
59751265
Alexander
Farber
1945522
http://cs319319.vk.me/v319319265/b7df/TnyKeffL_mU.jpg
0
MyAuth[3917:70b] Warning: Attempt to present <UserViewController: 0x8acbac0> on <UINavigationController: 0x8bb3a30> whose view is not in the window hierarchy!
更新3:感谢您宝贵的回答!我最终使用了Leonty Deriglazov的建议:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc1 = [storyboard instantiateViewControllerWithIdentifier:@"Master"];
//UIViewController *vc2 = [storyboard instantiateViewControllerWithIdentifier:@"Login"];
UIViewController *vc3 = [storyboard instantiateViewControllerWithIdentifier:@"User"];
User *user = [User load];
NSArray *controllers = (user ? @[vc1, vc3] : @[vc1]);
UINavigationController *nc = (UINavigationController *)self.window.rootViewController;
[nc setViewControllers:controllers];
return YES;
}
尝试在IB的属性检查器中为上一个UIViewController提供故事板ID。然后,在确定是否有用户处于NSUSerDefault时:
-获取对故事板的引用:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
-不满足上一个视图控制器的实例(请记住导入上一个视图控制器.h文件):
-向VC展示:
[self presentViewController:myController animated:YES completion:nil];
使用以下命令:
[self.presentingViewController dismissViewControllerAnimated:NO completion:^{
[self.presentingViewController dismissViewControllerAnimated:NO completion:nil];
}];
最好的方法是使用解卷
如果评论不清楚,则更新
我不知道
也许试试这个
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *uvc = [storyboard instantiateViewControllerWithIdentifier:@"Details"];
[self.window setRootViewController:uvc];
如果不是,则将UINavigationController设置为rootViewController,并将ivc设置为其rootViewController
希望对您有所帮助根据您的屏幕工作流程,您有一个导航控制器,其他视图控制器也被推入其中
因此,逻辑很简单:如果用户被缓存将details view controller设置为导航视图控制器的根目录,否则什么都不做(将使用情节提要的默认设置)
更新
如果需要返回到以前的视图控制器(例如从“详细信息”到“表格”),可以在导航控制器中设置整个导航层次结构:
UINavigationController *nc = (UINavigationController*)self.window.rootViewController;
if (hasUser) {
UIViewController *vc = [nc.storyboard instantiateViewControllerWithIdentifier:@"DetailsViewController"];
[nc pushViewController:vc animated:NO];
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *key = [defaults objectForKey:@"key"];
User *user = [User loadForKey:key];
if (!user) {
MasterViewController *loginController = [self.storyboard instantiateViewControllerWithIdentifier:@"MasterViewController"];
[self presentViewController:masterController animated:YES completion:nil];
}
我认为你的问题始于你最初的故事板设置。我会使用类似下图的东西
我将使用户视图控制器
成为我的根视图控制器,并以有动画或无动画的方式显示登录视图控制器
登录成功后,关闭视图控制器将非常方便。如果用户稍后注销,您只需再次显示登录视图控制器
我想你可以做到:
if (hasUser) {
MyFirstViewController *firstViewController = [myStoryboard instantiateViewControllerWithIdentifier:@"FirstViewControllerStoryboardId"];
SecondViewController *secondViewController = [myStoryboard instantiateViewControllerWithIdentifier:@"SecondViewControllerStoryboardId"];
[myNavigationController pushViewController:firstViewController animated:NO];
[myNavigationController pushViewController:secondViewController animated:YES];
}
这样,您将不会有任何动画,并且导航堆栈将得到尊重。
更改“动画”布尔值以播放动画
希望有帮助!破坏视图层次结构总是会产生奇怪的行为。
通过使用下面提到的方法,用户将无法注意到出现了LoginViewController,然后我们已推到详细信息屏幕。
这种方法一直对我有效
在LoginViewController.m文件中
- (void)viewDidLoad
{
if (user) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UserViewController *userViewController = [storyboard instantiateViewControllerWithIdentifier:@"Details"];
[self.navigationController pushViewController:listViewVC animated:YES];
}
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
if (user) {
self.navigationItem.hidesBackButton = YES;
}
}
在UserViewController.m文件中
- (void)viewDidLoad
{
if (user) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UserViewController *userViewController = [storyboard instantiateViewControllerWithIdentifier:@"Details"];
[self.navigationController pushViewController:listViewVC animated:YES];
}
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
if (user) {
self.navigationItem.hidesBackButton = YES;
}
}
在我的一个应用程序中,我要做的是从rootViewController
到要跳到的屏幕(在您的示例中,从MyAuth到Details)有一个额外的序列。然后,当我显示UINavigationController
时,我还在rootViewController
中设置一个变量,指定是否要跳到另一个屏幕。最后,在视图控制器的viewDidLoad:
中,我进行检查:
// Check if we want to skip to another screen
if (self.skipToDetails == YES) {
[self performSegueWithIdentifier:@"detailsView" sender:nil];
}
如果在情节提要文件中关闭此片段的动画,用户将根本看不到第一个屏幕
此外,您还需要在详细信息屏幕中将hidesBackButton
设置为YES
编辑:当您从原始(rootViewController
)移动到另一个VC(推送或模式)时,会发生“开始/结束的不平衡调用”
)在viewdiload:
中使用VC。将代码移动到viewdide:
应该会有所帮助。简而言之,最简单的解决方案是使用-[UINavigationController setViewControllers:animated:
您需要执行以下操作以实现您的目标:
将情节提要ID分配给所有控制器
从故事板实例化所有三个视图控制器(这是轻量级的,只要您不在控制器的构造函数中执行大多数初始化工作)
按照故事板中的顺序将它们放入数组中
使用数组作为第一个参数调用-[UINavigationController setViewControllers:
就是这样。-[AppDelegate应用程序:didFinishLaunchingWithOptions:
中的代码可能如下所示(当然,在检查了跳过条件之后):
如果您仅将此粘贴到-[AppDelegate应用程序:didFinishLaunchingWithOptions:
,您将看到它立即工作。@Alexander请检查屏幕截图您可以这样管理控制器:
并在用户视图控制器中使用以下代码:
UINavigationController *nc = (UINavigationController*)self.window.rootViewController;
if (hasUser) {
UIViewController *vc = [nc.storyboard instantiateViewControllerWithIdentifier:@"DetailsViewController"];
[nc pushViewController:vc animated:NO];
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *key = [defaults objectForKey:@"key"];
User *user = [User loadForKey:key];
if (!user) {
MasterViewController *loginController = [self.storyboard instantiateViewControllerWithIdentifier:@"MasterViewController"];
[self presentViewController:masterController animated:YES completion:nil];
}
我想你可以将另一个segue从视图1添加到视图4,然后触发I我可以按住ctrl键将segue从导航控制器拖动到最后一个视图吗?我不知道..也许可以试试这个UIStoryboa
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *key = [defaults objectForKey:@"key"];
User *user = [User loadForKey:key];
if (!user) {
MasterViewController *loginController = [self.storyboard instantiateViewControllerWithIdentifier:@"MasterViewController"];
[self presentViewController:masterController animated:YES completion:nil];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *key = [defaults objectForKey:@"key"];
User *user = [User loadForKey:key];
UINavigationController *navcon = (UINavigationController *)self.window.rootViewController;
if (hasUser) {
UIViewController *viewcon = [navcon.storyboard instantiateViewControllerWithIdentifier:@"DetailsViewController"];
[navcon pushViewController:viewcon animated:NO]; }
}
else
{
UIViewController *viewcon = [navcon.storyboard instantiateViewControllerWithIdentifier:@"UserViewController"];
[navcon pushViewController:viewcon animated:NO];}
}