确定视图是否位于 Popover 视图内部
我们在应用程序的 UINavigationControllers
内的许多位置都有常用的视图。有时,UINavigationController
位于弹出视图内。现在,我们放入导航控制器的视图会修改其导航控制器的工具栏按钮,并且在某些情况下,使用我们创建的自定义按钮。我们需要能够从 UIViewcontroller 本身判断视图是否位于 popoverview 内部,以便我们可以显示正确颜色的按钮。
我们可以使用 UIViewController.navigationController 轻松地从 UIViewController 获取导航控制器引用,但似乎没有任何东西可以找到 UIPopoverController 。
有人对如何做到这一点有什么好主意吗?
谢谢!
We have common views that we use in our application in many locations inside of UINavigationControllers
. Occasionally the UINavigationController
s are inside of popover views. Now the views we put into the nav controllers modify their navigation controller's toolbar buttons and, in some cases, use custom buttons that we've created. We need to be able to figure out from the UIViewcontroller
itself if the view is inside of a popoverview so we can display the correctly colored buttons.
We can easily get the Navigation controller reference from the UIViewController, using UIViewController.navigationController
, but there doesn't seem to be anything for finding a UIPopoverController
.
Does anyone have any good ideas for how to do this?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
正如 Artem 所说,从 iOS8 开始我们就有了
UIPopoverPresentationController
。例如,要确定视图是否在弹出窗口中,您可以使用其.arrowDirection
属性。在呈现的视图控制器的
viewWillApear()
中检查它:As Artem said we have
UIPopoverPresentationController
since iOS8. To determine if view is in popover you can use its.arrowDirection
property for example.Check it in
viewWillApear()
of presented view controller:这是另一个解决方案;定义一个只有一个方法的协议(例如 PopoverSensitiveController):
视图控制器想要知道它是否在弹出窗口中,然后定义一个属性 isInPopover;例如:
最后,在 splitView 委托中(假设您的应用程序使用拆分视图控制器):
然后,在视图控制器中的任何位置,您想知道您是否位于弹出窗口中,只需使用 isInPopover 属性即可。
Here's another solution; define a protocol (e.g. PopoverSensitiveController) that has only one method:
A view controller that wants to know if it is in a popover then defines a property isInPopover; for example:
Finally, in the splitView delegate (the assumption is that your app uses a split view controller):
Then where ever in the view controller you want to know if you are in a popover, simply use the isInPopover property.
在 iOS8 中,您可以使用 UIViewController 的 popoverPresentationController 属性来检查它是否包含在弹出框演示控制器中。从文档中,它返回:“视图控制器层次结构中最近的祖先是弹出框呈现控制器。(只读)”
In iOS8 you can use popoverPresentationController property of UIViewController to check if it is contained in a popover presentation controller. From documentation, it returns: "The nearest ancestor in the view controller hierarchy that is a popover presentation controller. (read-only)"
我最近正在寻找一种方法来确定视图是否显示在弹出窗口中。这就是我想到的:
基本上,您会爬上视图的超级视图树,查看其超级视图是否是 UIPopoverView。这里需要注意的是 UIPopoverView 类是一个未记录的私有类。我相信类名将来不会改变。 YMMV。
就您而言:
我很想看看是否有其他人提出更好的解决方案。
I was recently looking for a way to determine wether or not a view was being displayed in a popover. This is what I came up with:
Basically you climb the view's superview tree looking to see if any of its superviews is a UIPopoverView. The one caveat here is that the class UIPopoverView is an undocumented private class. I'm relying on the fact that the class name won't change in the future. YMMV.
In your case:
I'd be interested to see if anyone else comes up with a better solution.
对 iOS5.1 及更高版本已接受答案的修改:
** 注意 **
请参阅有关此代码可靠性的评论。
Modification of the accepted answer for iOS5.1 and newer:
** NOTE **
See comments about the reliability of this code.
我的方法是:(适用于 iOS 8 或更高版本)
父视图控制器将是导航控制器,如果在弹出窗口内,它将具有非零的
popoverPresentationController
属性。My approach for this: (available with iOS 8 or greater)
Parent view controller will be the navigation controller which if inside a popover, will have a non-nil
popoverPresentationController
property.通过使用 SpareTime 的代码,我得到了这个,它按预期工作。好的代码,好的解决方案:
使用标准的 UISplitViewController 示例。
By working with SpareTime's code I came to this, which works as expected. Nice code, nice solution:
Using the standard UISplitViewController example.
如果其他人仍在寻找解决方案,我想出了一个对我来说足够好的解决方案。
只需重写此方法,
这是 YourViewController 的一个示例,
如果它是弹出窗口,则不会调用“viewControllerForAdaptivePresentationStyle”方法,并且它将保持 true,如果它不是弹出窗口,则会将其设置为 false。
In case that someone else is still looking for a solution i came up with one good enough for me.
Just override this method
Here is an example of YourViewController
If it is popover it will not call 'viewControllerForAdaptivePresentationStyle' method and it will stay true, in case it is not popover it will set it to false.
如果视图未显示在弹出窗口中,我想在视图中放置一个按钮。我知道弹出框的宽度,因为我刚刚设置了它。这样我就可以测试我是否在iPad上以及框架的宽度是否与我设置的相同。
I wanted to put up a button in the view if the view wasn't displayed in a popover. I know the width of the popover because I just set it. So i can test whether I'm on an iPad and if the width of the frame is the same as what I set.
所有这些“精确类名匹配方法”很容易失败,甚至在 Apple 做出最微小的改变时也会出现故障。另外,执行 one-char-vars 和神秘的 for 循环并不完全适合我的风格。
我使用以下代码:
All these 'Exact Classname Matching Approaches' are very prone to fail and break at even the slightest changes Apple will make. Also doing one-char-vars and cryptic for-loops is not exactly a solution fitting to my style.
I use followingpiece of code:
上面所有的解决方案似乎都有点复杂。我使用一个名为
isInPopover
的变量,如果视图控制器出现在弹出窗口中,我将其设置为 true。在popoverControllerDidDismissPopover
或viewWillDisappear
的视图控制器中,我将布尔值设置为 false。它确实有效并且非常简单。All the solutions above seems a little bit complicated. I'm using a variable called
isInPopover
which I set to true if the view controller is presented in a popover. In the view controller inpopoverControllerDidDismissPopover
or inviewWillDisappear
I set the boolean value to false. It does work and is very simple.由于
self.popoverPresentationController
在最新的 iOS 版本中是延迟创建的,因此应该检查self.popoverPresentationController.presentingViewController
是否为 nil,如果不是 nil,则意味着self
当前显示在弹出窗口中。Since
self.popoverPresentationController
is created lazily in most recent iOS versions, one should check for nil-ness ofself.popoverPresentationController.presentingViewController
, if not nil this would meanself
is currently presented in a popover.Swift 4版本(可以在
扩展UIViewController
中添加功能):Swift 4 version (function can be added in
extension UIViewController
):