iOS中UIPopoverController使用詳解
一、引言
UIPopoverController是Pad設備中常用的一種視圖控制器,其在UI表現上為在當前視圖控制器上面彈出一個子視圖控制器,通常用來展示交互列表。示例如下圖:
UIPopoverController只能用於iPad,在要兼容iPad和iPhone的項目中,需要根據設備類型使用兩套代碼。在iOS8之後,系統提供了UIPresentationController來代替她,UIPresentationController可以兼容iPhone與iPad。
二、UIPopoverController的使用詳解
首先UIPopoverController是一個容器控制器,其中需要承載一個ViewControler作為內容視圖。UIPopoverController使用如下初始化方法創建:
//創建視圖控制器的方法 通過一個內容視圖控制器創建
- (instancetype)initWithContentViewController:(UIViewController *)viewController;
創建出控制器後,調用如下方法可以將控制器彈出:
//這個方法將控制器以一個CGRect區域為基準彈出
/*
UIPopoverArrowDirection為箭頭出現的方向
typedef NS_OPTIONS(NSUInteger, UIPopoverArrowDirection) {
UIPopoverArrowDirectionUp = 1UL << 0,//上
UIPopoverArrowDirectionDown = 1UL << 1,//下
UIPopoverArrowDirectionLeft = 1UL << 2,//左
UIPopoverArrowDirectionRight = 1UL << 3,//右
UIPopoverArrowDirectionAny = UIPopoverArrowDirectionUp | UIPopoverArrowDirectionDown | UIPopoverArrowDirectionLeft | UIPopoverArrowDirectionRight,//任意方向
UIPopoverArrowDirectionUnknown = NSUIntegerMax//未知
};
*/
//view參數為選擇要在那個View視圖上彈出 animated參數設置是否帶動畫
- (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated;
//以一個BarButtonItem為基準彈出 其余參數意義同上
- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated;
UIPopoverController的相關設置方法如下:
//設置代理
@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;
//這個屬性可以增強控制器的交互能力
/*
默認情況下,當視圖控制器彈出時,點擊界面上的其他位置,視圖控制器會被隱藏 如果需要當視圖控制愛彈出時界面上的其他控件依然可以進行用戶交互,則需要將這些UI控件設置進這個數組中
*/
@property (nullable, nonatomic, copy) NSArray<__kindof UIView *> *passthroughViews;
//隱藏視圖控制器的方法
- (void)dismissPopoverAnimated:(BOOL)animated;
//設置視圖控制器的背景顏色
@property (nullable, nonatomic, copy) UIColor *backgroundColor NS_AVAILABLE_IOS(7_0);
//設置視圖Margin
@property (nonatomic, readwrite) UIEdgeInsets popoverLayoutMargins NS_AVAILABLE_IOS(5_0);
//這個屬性用於自定義PopoverController的UI展現 傳入自定義的背景視圖類
@property (nullable, nonatomic, readwrite, strong) Class popoverBackgroundViewClass NS_AVAILABLE_IOS(5_0);
三、自定義UI展現的UIPopoverController
通過設置UIPopoverController對象的popoverBacjgroundViewClass屬性可以將一個自定義的類作為控制器的背景視圖,需要註意,此自定義的類必須繼承自UIPopoverBackgroundView,並且子類必須覆寫父類中的一些列方法,示例如下:
@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{
}
//重寫layout方法來來定義箭頭樣式
- (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結合進行,使用過程示例如下:
UITableViewController tabCon = [[UITableViewController alloc]initWithStyle:UITableViewStylePlain];
//設置跳轉模式為popover模式
tabCon.modalPresentationStyle = UIModalPresentationPopover;
//獲取到UIPopoverPresentationController對象
UIPopoverPresentationController* con = tabCon.popoverPresentationController;
//設置彈出的基準視圖
con.sourceView = self.view;
[self presentViewController:tabCon animated:YES completion:nil];
UIPopoverPresentationController中屬性如下:
//設置代理
@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);
//設置基準BarButtonItem
@property (nullable, nonatomic, strong) UIBarButtonItem *barButtonItem;
//設置可以進行用戶交互的視圖
@property (nullable, nonatomic, copy) NSArray<UIView *> *passthroughViews;
//設置背景顏色
@property (nullable, nonatomic, copy) UIColor *backgroundColor;
//設置Margin
@property (nonatomic, readwrite) UIEdgeInsets popoverLayoutMargins;
//設置自定義視圖
@property (nullable, nonatomic, readwrite, strong) Class <UIPopoverBackgroundViewMethods> popoverBackgroundViewClass;
UIPopoverPresentationControllerDelegate中的方法如下:
//控制器將要彈出時調用
- (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;
Tags: iPhone 控制器 項目
文章來源: