iOS在Objective-C中的登录/注销过程后更改rootViewController
我读过很多关于这个问题的问题,但我不知道什么不起作用 基本上,我想在用户登录或退出应用程序后更改我的根控制器。我也在使用故事板。 我的问题是iOS在Objective-C中的登录/注销过程后更改rootViewController,ios,objective-c,iphone,uiviewcontroller,uinavigationcontroller,Ios,Objective C,Iphone,Uiviewcontroller,Uinavigationcontroller,我读过很多关于这个问题的问题,但我不知道什么不起作用 基本上,我想在用户登录或退出应用程序后更改我的根控制器。我也在使用故事板。 我的问题是SILoginViewControllerdealloc的函数从未被调用,在这个控制器中,我发送了通知,而观察者没有被移除,所以它把一切都搞砸了,在多次“登录/注销”之后,它会收到多次通知 我的AppDelegate: - (BOOL)application:(UIApplication *)application didFinishLaunchingWit
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;
}
最简单的方法是直接向您显示故事板:
故事板中的实现可能看起来很奇怪,但我正在使用
我遵循了他们的故事板实现
问题是,SILoginViewController
dealloc的方法从未被调用
但顺便说一句,它工作得很好,从外观上看,我的意思是,当我运行应用程序时,它的行为是好的,但可以肯定的是,它会在以后搞砸
更新
我猜这是常见的行为,但是当根视图控制器被更改时,没有转换,当新控制器出现时,在很短的时间内会出现黑屏
在myAppDelegate.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];
}];
}
这可能是一个重复的问题,但我花了几个小时来解决这个问题
[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上没有任何内容,除非您在某处有指向它的指针,然后,需要将所有指向代码的指针置零。您尝试的解决方案只是成功完成转换所需的一半。在Google机器上查找transitionViewController。我就是这样做的。将rootViewController转换为新控制器。还有一些其他调用需要使其工作,它们应该会调用您的dealloc。我尝试了以下答案的解决方案:,它解决了我的转换问题,但没有解决有关解除分配的问题SILoginViewController
。您找到的解决方案似乎没有实现其他方法。当我到我的电脑前,我会把它们转发给你。好的,非常感谢。我添加了一个答案,上面有我想让你找到的所有代码。包括你的半解决方案没有实现的缺少的方法。我不知道该把那段代码放在哪里?此刻什么是自我?要从何处执行更改的ViewController?我已更新了我的问题,以显示我在我的AppDelegate
中添加了哪些内容,从而在我的应用程序中的任何位置更改rootViewController。我会将该代码放在您正试图进行更改的位置。赛尔夫当时可能是appDelegate。