在Xcode5.0.2中,我创建了一个iPhone应用程序(完整的应用程序code is on GitHub,请运行pod install
一次-适用于SDWebImage
),它显示社交网络(Facebook、Google+等)的列表,然后-在另一个视图中- UIWebView
显示OAuth2网页,然后是第三个视图,其中包含用户头像和详细信息(名、姓等):
(这里是上面显示的the fullscreen screenshot of the storyboard )
在最后一个视图中显示用户头像和详细信息之前,我将用户数据保存到NSUserDefaults
。
我的问题是:当用户下一次启动应用程序时,NSUserDefaults
中已经有用户数据-我如何跳过前2个视图并显示(没有任何动画)包含这些用户详细信息的最后一个视图?
我已将以下代码放入AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *key = [defaults objectForKey:@"key"];
User *user = [User loadForKey:key];
if (user) {
UINavigationController *nc = (UINavigationController*)self.window.rootViewController;
// XXX how to load the last view here? XXX
}
return YES;
}
可以看到,用户数据正在正常加载,但我不知道如何跳转到最后一个视图(例如,因为大多数UI都是在故事板中定义的)?
更新:我已经尝试了汤米·亚历山大的建议(谢谢!)使用AppDelegate.m中的以下代码(还将Details
StoryboardID分配给最后一个视图):
- (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;
}
虽然最后一个视图(带有用户头像和详细信息的UserViewController )似乎被实例化了,但我得到了以下警告,应用程序没有跳到最后一个视图:
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!
更新2:当我将上面的代码移动到第一个视图的viewDidLoad
( MasterViewController.m,用户可以在其中选择社交网络)时,我收到另一个警告:
MyAuth[1358:70b] XXX uvc=<UserViewController: 0x8a97430> user=
FB
597287941
Alexander
Farber
Bochum, Germany
http://graph.facebook.com/597287941/picture?type=large
0
MyAuth[1358:70b] Unbalanced calls to begin/end appearance transitions for <UINavigationController: 0x8a893e0>.
更新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;
}
发布于 2014-02-06 23:54:35
简而言之,最直接的解决方案是使用-[UINavigationController setViewControllers:animated:]
。
您需要执行以下操作才能实现您想要的结果:
-[UINavigationController setViewControllers:]
,并将该数组作为第一个参数。就这样。您的-[AppDelegate application:didFinishLaunchingWithOptions:]
中的代码可能如下所示(当然,在检查您的跳过条件之后):
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc1 = [storyboard instantiateViewControllerWithIdentifier:@"MyAuth"]; //if you assigned this ID is storyboard
UIViewController *vc2 = [storyboard instantiateViewControllerWithIdentifier:@"Login"]; //if you assigned this ID is storyboard
UIViewController *vc3 = [storyboard instantiateViewControllerWithIdentifier:@"Details"];
NSArray *controllers = @[vc1, vc2, vc3];
UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
[navController setViewControllers:controllers];
如果您只将其粘贴到-[AppDelegate application:didFinishLaunchingWithOptions:]
,您将看到它立即生效。
发布于 2014-02-06 20:33:40
打破视图层次结构总是会产生奇怪的行为。
通过使用下面提到的方法,用户将不会注意到显示了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];
}
}
UserViewController.m文件中的
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
if (user) {
self.navigationItem.hidesBackButton = YES;
}
}
发布于 2014-02-06 19:17:32
我认为你的问题从你的初始Storyboard设置开始。我会使用类似于下图的东西。
我会让User View controller
成为我的根视图控制器,并以带或不带动画的方式呈现登录视图控制器。
一旦登录成功,就可以很方便地关闭视图控制器。如果用户稍后注销,您只需再次显示登录视图控制器。
https://stackoverflow.com/questions/21537773
复制相似问题