使用UIPopoverPresentationController创建弹出视图

iOS8提供了一个非常好用的弹出视图控制器,用来做这种效果:

使用UIPopoverPresentationController创建弹出视图_第1张图片
类似钉钉
使用UIPopoverPresentationController创建弹出视图_第2张图片
类似系统剪切板,好像不常用

这个在iOS8以后可以很轻松的实现,用到的一个类叫UIPopoverPresentationController,UIViewController有一个属性,叫popoverPresentationController,是这个类的实例,是只读的,所以系统已经帮我们创建好了,拿来用就可以。

首先来看看UIPopoverPresentationController的头文件:

NS_CLASS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED @interface UIPopoverPresentationController : UIPresentationController

//控制声明周期的代理
@property (nullable, nonatomic, weak) id  delegate;

//允许的箭头方向,上下左右,当设置barButtonItem时,系统会自动设置
@property (nonatomic, assign) UIPopoverArrowDirection permittedArrowDirections;

//箭头指向的视图,当设置barButtonItem时,此属性无效
@property (nullable, nonatomic, strong) UIView *sourceView;

//箭头指向sourceView时,会有一个矩形框,箭头指向矩形框的中心点,可以通过这个属性,调整箭头的位置
@property (nonatomic, assign) CGRect sourceRect;

//默认情况下,弹出视图内容不能覆盖sourceView,如果内容比较多,系统会调整一个合适的大小。
@property (nonatomic, assign) BOOL canOverlapSourceViewRect NS_AVAILABLE_IOS(9_0);

//相对于UIBarButtonItem,比如钉钉那种效果;
@property (nullable, nonatomic, strong) UIBarButtonItem *barButtonItem;

//返回实际箭头方向
@property (nonatomic, readonly) UIPopoverArrowDirection arrowDirection;

//透传的view,正常情况下,弹框出来以后,下层视图就不能响应事件了,设置为透传view的除外
@property (nullable, nonatomic, copy) NSArray *passthroughViews;

@property (nullable, nonatomic, copy) UIColor *backgroundColor;

@property (nonatomic, readwrite) UIEdgeInsets popoverLayoutMargins;

//可以创建一个UIPopoverBackgroundView的子类,重写他的方法,自定义背景视图
@property (nullable, nonatomic, readwrite, strong) Class  popoverBackgroundViewClass;

@end

来看看图一的代码:

    QSTableViewController *dvc = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"QSTableViewController"];

    // 设置弹出视图控制器大小,iOS7出现的属性,用来定义子控制器的视图大小
    dvc.preferredContentSize = CGSizeMake(200, 200);
    
    // 设置弹出视图样式为popover
    dvc.modalPresentationStyle = UIModalPresentationPopover;
    
    // 设置为popover之后,控制器就有了这个属性
    UIPopoverPresentationController *presentationController =
    [dvc popoverPresentationController];
    
    // 设置委托协议
    presentationController.delegate = self;
    
    // 设置背景色
    presentationController.backgroundColor = dvc.view.backgroundColor;
    
    //设置ButtonItem
    presentationController.barButtonItem = sender;
    
    // 以模态形式呈现视图
    [self presentViewController:dvc animated:YES completion:nil];

接着看代理方法:

//弹出之前
- (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController{
    NSLog(@"prepareForPopoverPresentation");
}

//点击弹出视图以外的区域时是否可以自动消失
- (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController{
    NSLog(@"popoverPresentationControllerShouldDismissPopover");
    return YES;
}

//消失之后的代理,当自己主动dismiss的时候,不会走这个代理
- (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController{
    NSLog(@"popoverPresentationControllerDidDismissPopover");
}

//横竖屏切换的时候回调用
- (void)popoverPresentationController:(UIPopoverPresentationController *)popoverPresentationController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView  * __nonnull * __nonnull)view{
    
    NSLog(@"willRepositionPopoverToRect");
    
}

//返回none的时候才会有弹出框效果
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
    return UIModalPresentationNone;
}

图二跟图一的代码差不多,差别在于设置sourceView:

// 箭头所指的对应的视图,sourceRect 会以这个视图的左上角为原点.
    presentationController.sourceView = sender;
    
    // 箭头所指对应的区域.在 sourceView 描绘出一块区域(CGRect),然后箭头指向这块区域的中心点.
    presentationController.sourceRect = sender.bounds;
//    presentationController.canOverlapSourceViewRect = YES;
    
    // 设置箭头方向⬅️
    presentationController.permittedArrowDirections =
    UIPopoverArrowDirectionUp ;

使用起来非常方便,基本满足弹出框视图要求。

你可能感兴趣的:(使用UIPopoverPresentationController创建弹出视图)