如何识别出呈现UIViewController

sai*_*esh 26 iphone objective-c uiviewcontroller modalviewcontroller ios

我创建了一个UIViewController子类,它可以在UINavigationController的导航堆栈中推送,也可以从任何UIViewController呈现(模态).我需要确定是否显示了我的视图控制器,如果显示,我需要在视图控制器的顶部添加一个带有关闭按钮的工具栏.(否则,如果将其推入导航堆栈,则会添加默认关闭按钮,使用该用户可以返回.)

在UIViewController子类内部的所有可用版本中说4.3,5.0到6.0,如果满足以下条件,我可以假设视图控制器是以模态方式呈现的.

if(self.parentViewController == nil || self.navigationController == nil)
Run Code Online (Sandbox Code Playgroud)

dan*_*dee 35

在iOS 5中,UIViewController获得了一个名为readonly的属性presentingViewController,它替换了旧的语义parentViewController(现在描述了包含).当视图控制器需要访问提供它的视图控制器时,可以使用此属性 - 注意:如果您是API新手,这通常会超出您的预期!

此外,该isBeingPresented属性已被引入,几乎可以解决您当前所处的情况.在视图控制器中检查此属性viewWillAppear:.

更新

我overread你似乎定位到iOS 4.3,以及:
在这种情况下,你需要呼叫警卫isBeingPresentedif ([self respondsToSelector:…])然后你可以在else为parentViewController究竟是不是零块检查.

向后兼容性的另一种方法可能是覆盖+resolveInstanceMethod:-isBeingPresented在运行时添加实现.这将使您的呼叫站点保持干净,只要您放弃古老的iOS支持,您就可以摆脱运行时魔术;-)

但是请注意,有这样的边缘情况,并且在iOS <5上运行时也是初始方法:

视图控制器可以包含在任何其他视图控制器中,包括导航控制器.当这最后的情况下发生的,你的运气了:parentViewControllernil,同时navigationController不会.您可以尝试添加大量笨拙的代码来缓解旧iOS中的这种限制......或者您可以放手.


Eve*_*Loo 10

我使用此代码来检查是否显示了UIViewController.

if (uiviewcontroller.presentingViewController != nil) {
   // do something
}
Run Code Online (Sandbox Code Playgroud)


小智 8

我有一个类似的情况,但我提出的视图控制器包含在它自己的导航控制器中.因此在该视图控制器中,当我需要确定是否添加关闭按钮与后退按钮时,我只需检查导航控制器堆栈大小.如果显示屏幕,则堆栈大小应为1(需要关闭按钮)...如果使用现有导航控制器推送,则堆栈大小将大于1(需要后退按钮).

BOOL presented = [[self.navigationController viewControllers] count] == 1;
Run Code Online (Sandbox Code Playgroud)


Gl0*_*b1l 7

为了处理这种行为,我通常在viewWillAppear/viewWillDisappear方法中设置/重置BOOL切换它.

顺便说一下,你的测试条件似乎不正确.我想你应该用

if(self.parentViewController != nil || self.navigationController != nil)
Run Code Online (Sandbox Code Playgroud)

为什么不能一直将工具栏添加到视图控制器?是否有任何情况下加载视图但从未呈现过?


Ali*_*lil 5

在 iOS 9(或更高版本)上的 Swift 中:

if viewController.viewIfLoaded?.window != nil {
    // viewController is visible
}
Run Code Online (Sandbox Code Playgroud)