iOS在Objective-C中登录/注销过程后更改rootViewController
Posted
技术标签:
【中文标题】iOS在Objective-C中登录/注销过程后更改rootViewController【英文标题】:iOS Changing rootViewController after login / logout process in Objective-C 【发布时间】:2015-01-23 19:20:37 【问题描述】:我已经阅读了很多关于这个问题的问题,但我不知道它不起作用。
基本上我想在用户登录或退出应用程序后更改我的根控制器。我也在使用故事板。
我的问题是SILoginViewController
dealloc 的函数从未被调用,在这个控制器中我发送通知并且观察者没有被删除,所以它搞砸了一切,并且在几次“登录/注销”之后它收到了几个通知。
我的 AppDelegate :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
[self.window setFrame:[[UIScreen mainScreen] bounds]];
BOOL isLoggedIn = [[SIUser aUser] isLoggedIn]; // from your server response
NSString *storyboardId = isLoggedIn ? @"rootViewController" : @"navVcForLogin";
self.window.rootViewController = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:storyboardId];
return YES;
如果用户没有登录并且他成功发送通知的过程,这是我要更改 rootViewController 的处理程序:
- (void)loginSuccessHandler:(id)sender
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
SIRootViewController * vc = [sb instantiateViewControllerWithIdentifier:@"rootViewController"];
[UIApplication sharedApplication].keyWindow.rootViewController = vc;
这与注销的过程相同,这里是通知的处理程序:
- (void)logoutHandler:(id)sender
UIWindow *myWindow = [(SIAppDelegate *)[[UIApplication sharedApplication] delegate] window];
SILoginViewController * vc = [sb instantiateViewControllerWithIdentifier:@"navVcForLogin"];
[UIApplication sharedApplication].keyWindow.rootViewController = vc;
最简单的就是直接给你看故事板:
情节提要中的实现可能看起来很奇怪,但我使用的是https://github.com/romaonthego/RESideMenu
我关注了他们的故事板实现。
问题是SILoginViewController
dealloc 的方法永远不会被调用。
但顺便说一句,它运行良好,从外观上看,我的意思是,当我运行应用程序时,行为是好的,但它肯定会在以后搞砸。
更新
我猜这是常见的行为,但是当根视图控制器更改时没有过渡,并且在新控制器出现时有很短的时间黑屏。
在我的AppDelegate.m
中使用:解决了黑屏
- (void)changeRootViewController:(UIViewController*)newRootViewController
if (!self.window.rootViewController)
self.window.rootViewController = newRootViewController;
return;
UIView *snapShot = [self.window snapshotViewAfterScreenUpdates:YES];
[newRootViewController.view addSubview:snapShot];
self.window.rootViewController = newRootViewController;
[UIView animateWithDuration:0.3 animations:^
snapShot.layer.opacity = 0;
snapShot.layer.transform = CATransform3DMakeScale(1.5, 1.5, 1.5);
completion:^(BOOL finished)
[snapShot removeFromSuperview];
];
RootViewController Switch Transition Animation
这可能是一个重复的问题,但我花了几个小时才弄清楚这个问题。
【问题讨论】:
在 Google 机器上查找 transitionViewController。我就是这样做的。将 rootViewController 转换为新的。还需要其他一些调用才能使其正常工作,它们应该会调用你的 dealloc。 我尝试了这个答案的解决方案:***.com/questions/7703806/…,它解决了我的过渡问题,但不是关于解除分配SILoginViewController
的问题。
您找到的解决方案似乎没有实现其他方法。当我到达我的电脑时,我会重新发布它们。
好的,非常感谢。
我添加了一个答案,其中包含我想要让您找到的所有代码。包括您的半解决方案未实现的缺失方法。
【参考方案1】:
[currentRootViewController willMoveToParentViewController:nil]; // notify the VC of movements
[self addChildViewController:newRootViewController]; //Add the new VC
[self transitionFromViewController: currentRootViewController toViewController: newRootViewController
duration: 0.15 options:UIViewAnimationOptionCurveEaseInOut
animations:^
newRootViewController.view.frame = currentRootViewController.view.frame;
completion:^(BOOL finished) //Cleanup from the move
[currentRootViewController removeFromParentViewController];
[newRootViewController didMoveToParentViewController:self];
];
willMoveToParentViewController
和 didMoveToParentViewController
的代码将通知 ViewController 所做的更改,并且应该调用你的 dealloc,因为现在没有任何东西保留在 ViewController 上,除非你在某个地方有指向它的指针,否则你会需要取消所有指向代码的指针。您尝试的解决方案只是成功完成转换所需的一半。
【讨论】:
我不知道把那段代码放在哪里?此时self
是什么?我想从哪里执行更改的 ViewController ?
我已经更新了我的问题,以显示我已经准确添加到我的 AppDelegate
以更改我的应用程序中的 rootViewController。
我会将该代码准确地放在您尝试进行更改的位置。那时 Self 可能是 appDelegate。以上是关于iOS在Objective-C中登录/注销过程后更改rootViewController的主要内容,如果未能解决你的问题,请参考以下文章
Facebook SDK Objective-C 登录后触发事件
QuickBlox - 对话框必须在 Objective-C 的内存缓存中