UIPopoverPresentationController的使用

前言

最近项目中很多地方有一个相同的需求,那就是点击一个按钮的时候在按钮的某一个方向弹出一个视图,这个视图需要带有一个箭头指向,就像下图一样。要实现这个功能,就要用到UIPopoverPresentationController这个类了。


 
WechatIMG38.jpeg

简介

一个带有箭头的弹出视图从出现到消失的整个过程,都是UIPopoverPresentationController类的实例在管理,UIPopoverPresentationController类的实例管理着弹出视图的外形和其它的一些性质。

我们不需要直接去创建这个类的对象,当我们把这个弹出视图对应的视图控制器的modalPresentationStyle属性设置为UIModalPresentationPopover时,viewcontroller就会拥有一个popoverPresentationController属性,它就是UIPopoverPresentationController类型的,用它来管理这个弹出视图的外形和其它一些性质。

UIPopoverPresentationControllerDelegate

UIPopoverPresentationControllerDelegate对象会通知它的delegate整个弹出视图从弹出到消失的整个过程。下面是其主要的API:
通知delegate视图将要呈现:

- (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController;

询问delegate视图是否应该消失

- (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController;

通知delegate视图已经消失

- (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController;

相关属性

 
3E798BC1-2CF1-4634-8859-9EA7515BE1E4.png
  • backgroundColor
    上图中设置的backgroundColor是红色,上图中弹出视图是由两部分叠加的,一部分是上面的viewcontroller的View,其背景色是黄色,还有一部分是承载viewcontroller的View的视图,这个视图是由viewcontroller的popoverPresentationController对象来管理的。
  • passthroughViews
    这是一个数组,里面装着视图,一般情况下在弹出视图可见的情况下,点击界面上其他视图是无效的,这会导致弹出视图消失,但是这个数组中的视图不会这样,在弹出视图可见的情况下仍然可以点击这些视图。
  • canOverlapSourceViewRect
    这是一个布尔值,说明弹出视图是否可以和sourceRect重叠。
  • sourceView
    这个属性其实就是要指出弹出视图的箭头要指向哪个视图。
  • permittedArrowDirections
    这个属性要确定弹出视图的箭头的方法,它是一个枚举值,上图中设置的箭头方向是左边。
  • sourceRect
    有了sourceView和permittedArrowDirections还不能完全确定箭头的位置,还需要一个参数,这个参数就是sourceRect。上图中设置的sourceRect为_button.bnounds,当我们把sourceRect设置为CGRectMake(0, 0, _button.bounds.size.width, _button.bounds.size.height / 2.0);也即是这个按钮的上半区域的时候,我们看一下效果:
     
    0D46A23E-3BF1-4241-8A06-1BB92235F068.png

简单应用

    TestViewController *testVC = [[TestViewController alloc] init];
    testVC.preferredContentSize = CGSizeMake(150, 150);
    testVC.modalPresentationStyle = UIModalPresentationPopover;
    testVC.popoverPresentationController.delegate = self;
    testVC.popoverPresentationController.sourceView = _button;
    testVC.popoverPresentationController.sourceRect = CGRectMake(0, 0, _button.bounds.size.width / 2.0, _button.bounds.size.height / 2.0);
    testVC.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionLeft;
    testVC.popoverPresentationController.backgroundColor = [UIColor redColor];
    testVC.popoverPresentationController.canOverlapSourceViewRect = NO;
    [self presentViewController:testVC animated:YES completion:^{
        
    }];

注意,这样做的话是无论如何都不能成功显示弹出视图的,我们还需要实现代理的一个方法:

#pragma mark - <UIPopoverPresentationControllerDelegate>
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
    return UIModalPresentationNone;
}

这样就能成功实现了。

posted @ 2020-06-01 14:36  modentime  阅读(1703)  评论(0编辑  收藏  举报