Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.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 如何在任何时候(甚至在转换期间)或在安全的情况下关闭视图控制器?_Ios_Objective C_Uiviewcontroller_Uikit - Fatal编程技术网

Ios 如何在任何时候(甚至在转换期间)或在安全的情况下关闭视图控制器?

Ios 如何在任何时候(甚至在转换期间)或在安全的情况下关闭视图控制器?,ios,objective-c,uiviewcontroller,uikit,Ios,Objective C,Uiviewcontroller,Uikit,我有一个与服务器连接的iOS应用程序。如果我们断开连接,我希望能够关闭俯视图控制器,返回到“连接到服务器”视图控制器。问题在于,断开连接可能随时发生,包括在视图控制器之间的转换期间 视图控制器层次结构如下所示: 连接到服务器视图控制器 SignInViewController MainAppViewController 其他视图控制器 当检测到断开连接时,我希望视图层次折叠回: 连接到服务器视图控制器 因此,当检测到断开连接时,将在连接到服务器视图控制器上调用此方法,以排除它显示的任何内容,并返

我有一个与服务器连接的iOS应用程序。如果我们断开连接,我希望能够关闭俯视图控制器,返回到“连接到服务器”视图控制器。问题在于,断开连接可能随时发生,包括在视图控制器之间的转换期间

视图控制器层次结构如下所示:

  • 连接到服务器视图控制器
  • SignInViewController
  • MainAppViewController
  • 其他视图控制器
  • 当检测到断开连接时,我希望视图层次折叠回:

  • 连接到服务器视图控制器
  • 因此,当检测到断开连接时,将在
    连接到服务器视图控制器上调用此方法,以排除它显示的任何内容,并返回到尝试连接到服务器:

    - (void)restartSession
    {
        if (self.presentedViewController) {
            [self dismissViewControllerAnimated:NO completion:nil];
        }
    }
    
    但是,如果在视图转换发生时尝试取消,则会出现以下错误:

    *** Assertion failure in -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:], /SourceCache/UIKit/UIKit-2380.17/UIWindowController.m:211
    
    attempt to dismiss modal view controller whose view does not currently appear. self = <YYYYYViewController: 0x2089c8a0> modalViewController = <XXXXXViewController: 0x208e6610>
    attempt to dismiss modal view controller whose view does not currently appear. self = <WWWWWWViewController: 0x1fd9e990> modalViewController = <YYYYYViewController: 0x2089c8a0>
    
    ***在-[UIWindowController转换:从ViewController:到ViewController:目标:DiEndSelector:],/SourceCache/UIKit/UIKit-2380.17/UIWindowController.m:211中断言失败
    尝试关闭视图当前未出现的模态视图控制器。self=modalViewController=
    尝试关闭视图当前未出现的模态视图控制器。self=modalViewController=
    
    第一个将使应用程序崩溃,第二个将不会忽略任何内容并继续显示当前显示的视图控制器

    想法:

  • 因为我们不知道什么时候开始延迟,所以延迟不起作用
  • 是否有方法跟踪视图转换何时完成
  • 是否所有视图控制器都应覆盖WillDisplay、DidDisplay并在安全关闭时提醒应用程序
  • 也许我不应该放弃,而应该设置一个新的根视图控制器
  • 我已经确保所有被重写的视图(will | did)(dis)方法都会调用相应的超级方法
  • 任何要求所有视图控制器覆盖视图(did | will)的方法来跟踪状态的解决方案,如果我们忘记为新的视图控制器设置基类,听起来可能会导致问题

  • 当视图控制器当前不在屏幕上时,您似乎试图关闭它。要检查它是否在屏幕上,您可以使用:

    if (self.presentedViewController.view.window) 
    {
        [self dismissViewControllerAnimated:NO completion:nil];
    }
    else 
    {
        self.presentedViewController = nil;
    }
    

    像这样做。试试这个

    UIViewController *controller = self.presentingViewController; //THIS LINE IS IMP
    [self dismissViewControllerAnimated:YES
                                     completion:^{
                                         [controller presentViewController:adminViewController animated:YES completion:nil];
                                         adminViewController.view.superview.frame    = CGRectMake(1024/2 - 400, 768/2 - 280, 800 , 560);//it's important to do this after
                                         [adminViewController release];
                                     }]; 
    

    一种对我有效的方法是将新的视图控制器分配给根视图控制器。这样,旧层次结构中的视图可以设置动画并过渡到其核心内容,而我们有了新的控制器

    乙二醇

    不过,我不确定我是否意识到这一切的不利因素。也许旧的视图控制器永远不会因为悬空的强引用而被释放?我们不再重用ConnectiontoServerViewController,每次都必须重新创建它


    我根据在中看到的内容编写代码。

    我将按顺序回答

    是否有方法跟踪视图转换何时完成

    您可以尝试使用(如果您正在使用其中一个)。另一种方法可以是使用自定义动画

    是否所有视图控制器都应覆盖WillDisplay、DidDisplay并在安全关闭时提醒应用程序

    这是一个选择。如果你愿意,你可以自由地去做。另一个选择是不这样做。我认为容器视图控制器(如导航控制器)有更好的方法

    我应该设置一个新的根视图控制器吗

    我建议做相反的事情。我会将
    SignInViewController/MainAppViewController
    设置为根流,并根据需要显示与ServerViewController的模式连接。在我看来,这是一个更健康的方法


    希望对您有所帮助。

    如果您可以在viewController中设置任何标志变量,并且当您从服务器断开连接时,如果未加载视图,则可以从RestSession方法更改标志。因此,当视图加载时,它会自动将其自行关闭。你可以用这样的逻辑。。。希望能有所帮助1.我在接近尾声时谈到了这一点。我想避免这样的解决方案,即要求所有视图控制器都必须为一个特殊的viewcontroller类创建子类,以便跟踪状态。如何延迟解除该类,或者通过将解除放入:NSOperationQueue.mainQueue().addOperationWithBlock{//Disease}中,将其解除在主队列上//swift CODE在调用完成块之前可以发生断言。调用DismissViewControllerInitiated:completion时,会发生此断言:**在-[UIWindowController转换:从ViewController:到ViewController:目标:DiEndSelector:]中发生断言失败,/SourceCache/UIKit/UIKit-2380.17/UIWindowController.m:211甚至在调用完成块之前。如果您正在演示下一个VC,只要检查一下ViewDidDisplay中的代码就可以了。听起来不是每个视图控制器都应该检查ViewDidDisplay。但是,当显示的视图控制器最终可见时,我仍然需要关闭?如果它不在屏幕上,您可以在viewController中设置一个标志,指示模式视图需要关闭。然后在您的视图中将出现:您可以检查该标志,并在必要时取消该标志。不确定这个原因,我从来没有做过,但只是一个想法。人力资源管理,我们可能不得不这样做,但我想避免让每个视图控制器都必须检查是否需要自行关闭。感觉我们可能会忘记为新的viewcontroller执行此操作。另外,我们有很多视图控制器。如果模式视图控制器在屏幕外,您是否尝试过将其设置为零?
    - (void)restartSession
    {
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
        ConnectingToServerViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"ConnectingToServerViewController"];
        vc.modalPresentationStyle = UIModalPresentationFullScreen;
        [UIApplication sharedApplication].delegate.window.rootViewController = vc;
    }