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