iOS8提供了一个非常好用的弹出视图控制器,用来做这种效果:
类似钉钉 类似系统剪切板,好像不常用这个在iOS8以后可以很轻松的实现,用到的一个类叫UIPopoverPresentationController,UIViewController有一个属性,叫popoverPresentationController,是这个类的实例,是只读的,所以系统已经帮我们创建好了,拿来用就可以。
首先来看看UIPopoverPresentationController的头文件:
NS_CLASS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED @interface UIPopoverPresentationController : UIPresentationController
//控制声明周期的代理
@property (nullable, nonatomic, weak) id <UIPopoverPresentationControllerDelegate> 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<UIView *> *passthroughViews;
@property (nullable, nonatomic, copy) UIColor *backgroundColor;
@property (nonatomic, readwrite) UIEdgeInsets popoverLayoutMargins;
//可以创建一个UIPopoverBackgroundView的子类,重写他的方法,自定义背景视图
@property (nullable, nonatomic, readwrite, strong) Class <UIPopoverBackgroundViewMethods> 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 ;
使用起来非常方便,基本满足弹出框视图要求。
网友评论