美文网首页iOS开发技巧
使用UIPopoverPresentationControlle

使用UIPopoverPresentationControlle

作者: 青山不改 | 来源:发表于2017-10-25 16:05 被阅读244次

    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 ;
    

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

    相关文章

      网友评论

        本文标题:使用UIPopoverPresentationControlle

        本文链接:https://www.haomeiwen.com/subject/cdvqpxtx.html