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 @   modentime  阅读(1731)  评论(0编辑  收藏  举报
    编辑推荐:
    · 如何编写易于单元测试的代码
    · 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
    · .NET Core 中如何实现缓存的预热?
    · 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
    · AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
    阅读排行:
    · 地球OL攻略 —— 某应届生求职总结
    · 周边上新:园子的第一款马克杯温暖上架
    · Open-Sora 2.0 重磅开源!
    · 提示词工程——AI应用必不可少的技术
    · .NET周刊【3月第1期 2025-03-02】
    点击右上角即可分享
    微信分享提示