iOS中UIPopoverController使用详解
一、引言
UIPopoverController是Pad设备中常用的一种视图控制器,其在UI表现上为在当前视图控制器上面弹出一个子视图控制器,通常用来展示交互列表。示例如下图:
UIPopoverController只能用于iPad,在要兼容iPad和iPhone的项目中,需要根据设备类型使用两套代码。在iOS8之后,系统提供了UIPresentationController来代替她,UIPresentationController可以兼容iPhone与iPad。
二、UIPopoverController的使用详解
首先UIPopoverController是一个容器控制器,其中需要承载一个ViewControler作为内容视图。UIPopoverController使用如下初始化方法创建:
1 2
| - (instancetype)initWithContentViewController:(UIViewController *)viewController;
|
创建出控制器后,调用如下方法可以将控制器弹出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
- (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated;
- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated;
|
UIPopoverController的相关设置方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @property (nullable, nonatomic, weak) id <UIPopoverControllerDelegate> delegate;
@property (nonatomic, strong) UIViewController *contentViewController; - (void)setContentViewController:(UIViewController *)viewController animated:(BOOL)animated;
@property (nonatomic) CGSize popoverContentSize; - (void)setPopoverContentSize:(CGSize)size animated:(BOOL)animated;
@property (nonatomic, readonly, getter=isPopoverVisible) BOOL popoverVisible;
@property (nonatomic, readonly) UIPopoverArrowDirection popoverArrowDirection;
@property (nullable, nonatomic, copy) NSArray<__kindof UIView *> *passthroughViews;
- (void)dismissPopoverAnimated:(BOOL)animated;
@property (nullable, nonatomic, copy) UIColor *backgroundColor NS_AVAILABLE_IOS(7_0);
@property (nonatomic, readwrite) UIEdgeInsets popoverLayoutMargins NS_AVAILABLE_IOS(5_0);
@property (nullable, nonatomic, readwrite, strong) Class popoverBackgroundViewClass NS_AVAILABLE_IOS(5_0);
|
三、自定义UI展现的UIPopoverController
通过设置UIPopoverController对象的popoverBacjgroundViewClass属性可以将一个自定义的类作为控制器的背景视图,需要注意,此自定义的类必须继承自UIPopoverBackgroundView,并且子类必须覆写父类中的一些列方法,示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| @interface MyView : UIPopoverBackgroundView @end
@implementation MyView
+ (CGFloat)arrowBase{ return 20; }
+(UIEdgeInsets)contentViewInsets{ return UIEdgeInsetsMake(20, 20, 20, 20); }
+(CGFloat)arrowHeight{ return 30; }
-(UIPopoverArrowDirection)arrowDirection{ return UIPopoverArrowDirectionUp; }
-(void)setArrowDirection:(UIPopoverArrowDirection)arrowDirection{ }
-(void)setArrowOffset:(CGFloat)arrowOffset{ }
- (void)layoutSubviews { [super layoutSubviews]; CGSize arrowSize = CGSizeMake([[self class] arrowBase], [[self class] arrowHeight]); UIImage * image = [self drawArrowImage:arrowSize]; UIImageView * imageView = [[UIImageView alloc]initWithImage:image]; imageView.frame = CGRectMake(0, 0.0f, arrowSize.width, arrowSize.height); [self addSubview:imageView]; }
- (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor redColor]; } return self; } - (instancetype)init { self = [super init]; if (self) { } return self; }
+(BOOL)wantsDefaultContentAppearance{ return NO; }
- (UIImage *)drawArrowImage:(CGSize)size { UIGraphicsBeginImageContextWithOptions(size, NO, 0); CGContextRef ctx = UIGraphicsGetCurrentContext(); [[UIColor clearColor] setFill]; CGContextFillRect(ctx, CGRectMake(0.0f, 0.0f, size.width, size.height)); CGMutablePathRef arrowPath = CGPathCreateMutable(); CGPathMoveToPoint(arrowPath, NULL, (size.width/2.0f), 0.0f); CGPathAddLineToPoint(arrowPath, NULL, size.width, size.height); CGPathAddLineToPoint(arrowPath, NULL, 0.0f, size.height); CGPathCloseSubpath(arrowPath); CGContextAddPath(ctx, arrowPath); CGPathRelease(arrowPath); UIColor *fillColor = [UIColor yellowColor]; CGContextSetFillColorWithColor(ctx, fillColor.CGColor); CGContextDrawPath(ctx, kCGPathFill); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } @end
|
四、UIPopoverPresentationController应用解析
UIPopoverPresentationController是iOS8后系统新引入的控制器,其可以很好的兼容iPhone与iPad。UIPopoverPresentationContriller的使用需要和UIViewController结合进行,使用过程示例如下:
1 2 3 4 5 6 7 8
| UITableViewController tabCon = [[UITableViewController alloc]initWithStyle:UITableViewStylePlain];
tabCon.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController* con = tabCon.popoverPresentationController;
con.sourceView = self.view; [self presentViewController:tabCon animated:YES completion:nil];
|
UIPopoverPresentationController中属性如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @property (nullable, nonatomic, weak) id <UIPopoverPresentationControllerDelegate> delegate;
@property (nonatomic, assign) UIPopoverArrowDirection permittedArrowDirections;
@property (nullable, nonatomic, strong) UIView *sourceView; @property (nonatomic, assign) CGRect sourceRect;
@property (nonatomic, assign) BOOL canOverlapSourceViewRect NS_AVAILABLE_IOS(9_0);
@property (nullable, nonatomic, strong) UIBarButtonItem *barButtonItem;
@property (nullable, nonatomic, copy) NSArray<UIView *> *passthroughViews;
@property (nullable, nonatomic, copy) UIColor *backgroundColor;
@property (nonatomic, readwrite) UIEdgeInsets popoverLayoutMargins;
@property (nullable, nonatomic, readwrite, strong) Class <UIPopoverBackgroundViewMethods> popoverBackgroundViewClass;
|
UIPopoverPresentationControllerDelegate中的方法如下:
1 2 3 4 5 6 7 8
| - (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController;
- (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController;
- (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController;
- (void)popoverPresentationController:(UIPopoverPresentationController *)popoverPresentationController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView * __nonnull * __nonnull)view;
|
专注技术,热爱生活,交流技术,也做朋友。
——珲少 QQ群:203317592