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];
                        ];

willMoveToParentViewControllerdidMoveToParentViewController 的代码将通知 ViewController 所做的更改,并且应该调用你的 dealloc,因为现在没有任何东西保留在 ViewController 上,除非你在某个地方有指向它的指针,否则你会需要取消所有指向代码的指针。您尝试的解决方案只是成功完成转换所需的一半。

【讨论】:

我不知道把那段代码放在哪里?此时self 是什么?我想从哪里执行更改的 ViewController ? 我已经更新了我的问题,以显示我已经准确添加到我的 AppDelegate 以更改我的应用程序中的 rootViewController。 我会将该代码准确地放在您尝试进行更改的位置。那时 Self 可能是 appDelegate。

以上是关于iOS在Objective-C中登录/注销过程后更改rootViewController的主要内容,如果未能解决你的问题,请参考以下文章

持久登录 iOS Objective-C

Facebook SDK Objective-C 登录后触发事件

QuickBlox - 对话框必须在 Objective-C 的内存缓存中

在 iOS 中单击注销时发生 Facebook 登录?

如何在 Nest API iOS 中成功注销后重新加载登录页面

如何在 iOS Objective-C 中集成“使用 Apple 登录”流程?