mjd*_*dth 16 objective-c ipad uipopovercontroller
我们在我们的应用程序中使用了很多共同的视图UINavigationControllers.偶尔UINavigationControllers会在popover视图中.现在我们放入导航控制器的视图会修改导航控制器的工具栏按钮,在某些情况下,还会使用我们创建的自定义按钮.我们需要能够从UIViewcontroller自身中找出视图是否在popoverview中,以便我们可以显示正确颜色的按钮.
我们可以很容易地从UIViewController获取导航控制器参考UIViewController.navigationController,但是似乎找不到任何东西UIPopoverController.
有没有人对如何做到这一点有任何好的想法?
谢谢!
小智 8
由于阿尔乔姆说我们有UIPopoverPresentationController自iOS8上.要确定视图是否在弹出窗口中,您可以使用其.arrowDirection属性作为示例.
检查viewWillApear()呈现的视图控制器:
// get it from parent NavigationController
UIPopoverPresentationController* popoverPresentationVC = self.parentViewController.popoverPresentationController;
if (UIPopoverArrowDirectionUnknown > popoverPresentationVC.arrowDirection) {
// presented as popover
} else {
// presented as modal view controller (on iPhone)
}
Run Code Online (Sandbox Code Playgroud)
这是另一个解决方案; 定义一个只有一个方法的协议(例如PopoverSensitiveController):
#import "Foundation/Foundation.h" @protocol PopoverSensitiveController -(void) setIsInPopover:(BOOL) inPopover; @end
想要知道它是否在弹出框中的视图控制器然后定义属性isInPopover; 例如:
#import
#import "PopoverSensitiveController.h"
#pragma mark -
#pragma mark Interface
@interface MyViewController : UIViewController {
}
#pragma mark -
#pragma mark Properties
@property (nonatomic) BOOL isInPopover;
#pragma mark -
#pragma mark Instance Methods
...other stuff...
@end
最后,在splitView委托中(假设您的应用程序使用拆分视图控制器):
#import "MySplitViewControllerDelegate.h"
#import "SubstitutableDetailViewController.h"
#import "PopoverSensitiveController.h"
#pragma mark -
#pragma mark Implementation
@implementation MySplitViewControllerDelegate
#pragma mark -
#pragma mark UISplitViewControllerDelegate protocol methods
-(void) splitViewController:(UISplitViewController *) splitViewController willHideViewController:(UIViewController *) aViewController withBarButtonItem:(UIBarButtonItem *) barButtonItem forPopoverController:(UIPopoverController *) pc {
// Keep references to the popover controller and the popover button, and tell the detail view controller to show the button
popoverController = [pc retain];
popoverButtonItem = [barButtonItem retain];
if ([[splitViewController.viewControllers objectAtIndex:1] respondsToSelector:@selector(showRootPopoverButtonItem:)]) {
UIViewController *detailViewController = [splitViewController.viewControllers objectAtIndex:1];
[detailViewController showRootPopoverButtonItem:barButtonItem];
}
if ([[splitViewController.viewControllers objectAtIndex:1] respondsToSelector:@selector(showRootPopoverButtonItem:)]) {
UIViewController *detailViewController = [splitViewController.viewControllers objectAtIndex:1];
[detailViewController showRootPopoverButtonItem:barButtonItem];
}
// If the view controller wants to know, tell it that it is a popover
if ([aViewController respondsToSelector:@selector(setIsInPopover:)]) {
[(id) aViewController setIsInPopover:YES];
}
// Make sure the proper view controller is in the popover controller and the size is as requested
popoverController.contentViewController = aViewController;
popoverController.popoverContentSize = aViewController.contentSizeForViewInPopover;
}
-(void) splitViewController:(UISplitViewController *) splitViewController willShowViewController:(UIViewController *) aViewController invalidatingBarButtonItem:(UIBarButtonItem *) barButtonItem {
// Tell the detail view controller to hide the button.
if ([[splitViewController.viewControllers objectAtIndex:1] respondsToSelector:@selector(invalidateRootPopoverButtonItem:)]) {
UIViewController *detailViewController = [splitViewController.viewControllers objectAtIndex:1];
[detailViewController invalidateRootPopoverButtonItem:barButtonItem];
}
// If the view controller wants to know, tell it that it is not in a popover anymore
if ([aViewController respondsToSelector:@selector(setIsInPopover:)]) {
[(id) aViewController setIsInPopover:NO];
}
// Now clear out everything
[popoverController release];
popoverController = nil;
[popoverButtonItem release];
popoverButtonItem = nil;
}
-(void) setPopoverButtonForSplitViewController:(UISplitViewController *) splitViewController {
// Deal with the popover button
UIViewController *detailViewController = [splitViewController.viewControllers objectAtIndex:1];
[detailViewController showRootPopoverButtonItem:popoverButtonItem];
// If the view controller wants to know, tell it that it is a popover (initialize the controller properly)
if ([[splitViewController.viewControllers objectAtIndex:0] respondsToSelector:@selector(setIsInPopover:)]) {
[(id) [splitViewController.viewControllers objectAtIndex:0] setIsInPopover:YES];
}
}
然后在视图控制器中您想知道您是否在弹出窗口中,只需使用isInPopover属性即可.
在iOS8中,您可以使用UIViewController的popoverPresentationController属性来检查它是否包含在弹出窗口控制器中.从文档中,它返回:"视图控制器层次结构中最近的祖先是一个弹出式表示控制器.(只读)"
我最近正在寻找一种方法来确定视图是否显示在弹出窗口中。这就是我想出的:
UIView *v=theViewInQuestion;
for (;v.superview != nil; v=v.superview) {
if (!strcmp(object_getClassName(v), "UIPopoverView")) {
NSLog(@"\n\n\nIM IN A POPOVER!\n\n\n\n");
}
Run Code Online (Sandbox Code Playgroud)
基本上,您会爬上视图的超级视图树,查看其超级视图中是否有 UIPopoverView。这里需要注意的是 UIPopoverView 类是一个未记录的私有类。我相信类名将来不会改变。YMMV。
在你的情况下:
theViewInQuestion = theViewControllerInQuestion.view;
Run Code Online (Sandbox Code Playgroud)
我很想看看是否有其他人提出更好的解决方案。
| 归档时间: |
|
| 查看次数: |
9685 次 |
| 最近记录: |