Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS在Objective-C中的登录/注销过程后更改rootViewController_Ios_Objective C_Iphone_Uiviewcontroller_Uinavigationcontroller - Fatal编程技术网

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的方法从未被调用

但顺便说一句,它工作得很好,从外观上看,我的意思是,当我运行应用程序时,它的行为是好的,但可以肯定的是,它会在以后搞砸

更新

我猜这是常见的行为,但是当根视图控制器被更改时,没有转换,当新控制器出现时,在很短的时间内会出现黑屏

在my
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];
    }];
}

这可能是一个重复的问题,但我花了几个小时来解决这个问题

[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。