美文网首页
iOS开发-Popover的使用

iOS开发-Popover的使用

作者: 张囧瑞 | 来源:发表于2020-01-01 21:48 被阅读0次

    A popover is a transient view that appears above other content onscreen when you tap a control or in an area.

    以上内容来自苹果官方人机交互指南中对Popover的简介。

    简单来说Popover就是一个在正常操作流程中短暂出现的一个控制区域,一般会出现在iPad这类大屏设备中,并且包含一个指向的view和箭头,比如官方文档中给出的这个日历中添加事项的视图。

    截屏2019-12-28下午3.38.27.png

    一般情况下,一个Popover分为模态结构(modal)和非模态结构(nonmodal),在非模态结构中,通常通过点击其他区域来关闭Popover,
    在模态结构中,通过通过点击页面中的取消按钮来关闭Popover。

    在苹果官方人机交互文档中,苹果建议使用Popover时遵循这些原则:

    • 避免在iPhone上使用Popover
    • 使用一个明确的关闭按钮
    • 在关闭时自动保存Popover中的状态
    • 在屏幕中找到一个合适的位置弹出Popover
    • 一次只显示一个Popover
    • 不要将Popover放的太大

    更多遵循的原则和详细的解析可以参看官方文档对Popover的介绍,链接在最下边参考文档中👇👇👇

    接下来我们来看一下如何在iOS中使用Popover。

    UIPopoverController

    UIPopoverController是专为iPad设计的一个Controller,所以在iPhone中如果使用它会造成崩溃。

    不过这个UIPopoverController在iOS9中被苹果弃用了,取而代之的是UIPopoverPresentationController,因为UIPopoverPresentationController支持iOS8+,所以在这个iOS13的时代,我们就不多介绍UIPopoverController了。

    UIPopoverPresentationController

    UIPopoverPresentationController基本上包括了之前说的UIPopoverController的特性,并且他也可以支持iPhone使用。

    那么我们如何来使用它呢,苹果官方文档中有这样一句话:

    In nearly all cases, you use this class as-is and do not create instances of it directly. UIKit creates an instance of this class automatically when you present a view controller using the UIModalPresentationStyle.popover style. You can retrieve that instance from the presented view controller’s popoverPresentationController property and use it to configure the popover behavior.

    也就是说,我们不需要直接创建UIPopoverPresentationController的实例,当我们创建一个present的Controller时,使用Popover的样式,系统就会自动为我们创建一个实例,我们可以直接通过使用它的 popoverPresentationController属性来对他进行操作。

    那么根据官方文档,我们通过简单三行代码,就能创建出一个简单的Popover了。

    
            let popoverVC = PopoverViewController();
            popoverVC.modalPresentationStyle = .popover;
            self.present(popoverVC, animated: true, completion: nil);
    
    

    然后愉快的在iPhone上测试一下

    截屏2019-12-28下午4.29.52.png

    发现和正常的present好像没什么区别,那看看iPad的上表现吧,运行起来之后,发现程序崩溃了,仔细看一下崩溃的信息

    *** Terminating app due to uncaught exception ‘NSGenericException’, reason: ‘UIPopoverPresentationController (<UIPopoverPresentationController: 0x7ffe9c71fcc0>) should have a non-nil sourceView or barButtonItem set before the presentation occurs.’
    ***
    

    原来是需要一个sourceView或者barButtonItem,在iPad中使用过UIAlertController应该对这个崩溃信息不陌生。那么除了要设置这个,如果定制一个Popover我们还需要使用些什么呢?

    因为整个Popover基本上都是用于iPad的,并且苹果官方也不太建议在iPhone上使用,所以接下来的部分我们就不涉及在iPhone中使用Popover了,所有的内容都以iPad为标准介绍。

    barButtonItem

    这个属性一般用于点击导航栏的barButtonItem时显示Popover,他会自动设置Popover的SourceView和SourceRect,设定了之后,再在iPad上跑起来,点击导航栏上的Popover按钮,就可以看到,Popover已经弹出来了。

            let popoverVC = PopoverViewController();
            popoverVC.modalPresentationStyle = .popover;
            popoverVC.popoverPresentationController?.barButtonItem = self.barItem
            self.present(popoverVC, animated: true, completion: nil);
    
    截屏2019-12-28下午4.53.52.png

    sourceView 和 sourceRect

    但是我们往往需求中,要求Popover不是指向于一个barButtonItem,而是我们自定义的一个view和位置,这时候就需要用到这两个属性了。

    sourceView为我们的Popover指向的view;
    sourceRect为我们指向的基于sourceView的位置,默认为CGRectZero。

    也就是说,默认情况下,这段代码的指向是这样的(截图中红框为button的frame):

    
            let popoverVC = PopoverViewController();
            popoverVC.modalPresentationStyle = .popover;
            popoverVC.popoverPresentationController?.sourceView = self.popoverBtn;
            popoverVC.popoverPresentationController?.sourceRect = CGRect.zero;
            self.present(popoverVC, animated: true, completion: nil);
    
    
    截屏2019-12-28下午5.05.01.png

    那么,如果我们想要将箭头指向button的下部中间位置,我们需要修改sourceRect

            popoverVC.popoverPresentationController?.sourceRect = CGRect.init(x: self.popoverBtn.frame.size.width/2.0, y: self.popoverBtn.frame.size.height, width: 0, height: 0);
    
    截屏2019-12-28下午5.07.52.png

    permittedArrowDirections

    这个属性表示的是允许的方向,这个应该很好理解,就不多做介绍了。

    arrowDirection

    这个属性表示箭头指向的方向,在弹出Popover之前,这个属性为unknow。

    修改Popover的大小

    在popoverPresentationController中,并没有修改Popover的大小的属性,我们需要使用UIViewController中的preferredContentSize属性来修改Popover的大小。

    这样一来,定制一个Popover的基本操作就完成了。

    如下代码就可以展示出一个这样的Popover,当然Popover中的具体内容,可以直接在Popover的Controller中绘制。

            let popoverVC = PopoverViewController();
            popoverVC.modalPresentationStyle = .popover;
            popoverVC.popoverPresentationController?.sourceView = self.popoverBtn;
            popoverVC.popoverPresentationController?.sourceRect = CGRect.init(x: self.popoverBtn.frame.size.width/2.0, y: self.popoverBtn.frame.size.height, width: 0, height: 0);
            popoverVC.popoverPresentationController?.permittedArrowDirections = .up;
            popoverVC.preferredContentSize = CGSize.init(width: 100, height: 50);
            self.present(popoverVC, animated: true, completion: nil);
    
    截屏2019-12-28下午5.16.36.png

    外观属性

    另外还有一些控制Popover外观的属性,比如:

    • popoverLayoutMargins:定义Popover允许展示的区域之前的间隙
    • backgroundColor:背景色
    • passthroughViews:当Popover显示的时候,当前Controller其他可以交互的view
    • popoverBackgroundViewClass:自定义Popover的箭头高度位置等等
    • canOverlapSourceViewRect:Popover是否与sourceView重叠

    等等。这些属性都很好理解,在使用的时候不明白的地方查查官方文档就都很清楚了。

    最后

    以上就是在iOS中使用Popover的一些简单介绍,主要还是以UIPopoverPresentationController为主,当然了还有一些其他的比如在iPad中使用UIAlertController时也会遇到这个问题。但是基本上也都是一样的东西,这里也就不多赘述了。

    本文章仅限个人学习使用,如果有什么问题欢迎大家批评指正。

    参考文档

    Popovers - Views - iOS - Human Interface Guidelines - Apple Developer

    UIPopoverPresentationController - UIKit | Apple Developer Documentation

    UIPopoverController - UIKit | Apple Developer Documentation

    相关文章

      网友评论

          本文标题:iOS开发-Popover的使用

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