参考:
首先说下需求,就是一个自定义的模态弹出框
对于弹出框,我们首先想到的就是UIAlertController这个类。但是这个类只能创建两种类型的弹出框,actionSheet和alert。要想使用这个类实现上面的效果,很难,之前为了实现这个效果在网上找来找去,最后使用了View叠加View的方式,也就是一个大的View当做背景,中间的控件使用一个View来实现。这种方法有个缺点,就是当显示后,导航栏的按钮,比如返回按钮还是可以点击的,也就是整个View并不能覆盖真个屏幕,实现真正的模态。而且使用View看起来效果也不好。
那么下面就来说说怎么实现上面图中的效果,真正的模态弹出框。
要实现上面的效果,首先我们需要一个ViewController来实现要弹出的框,也就是上图中的时间选择部分,那么谁来控制这个ViewController的显示呢?我们就需要下面一个类
有一个类是必不可少的:UIPresentationController,这个类看起来很陌生。我们知道从一个ViewController跳转到另一个,有两种方式:
1)经常使用的是push的方式,控制器从屏幕的右边弹出来,显示的控制器带有返回按钮
2) 还有一种方式就是present,这种方式可能不经常使用,默认的效果是从屏幕底部弹出来的,并占满整个屏幕,没有返回按钮
上面的时间选择弹出框就是通过第二种方式实现的,在我们调用present的时候,系统会提供一个默认的UIPresentationController,但是UIKit默认的实现不能满足我们的需求,但是这个类是可以自定义的,用来控制present的方式。
那个这个UIPresentationController可以用来干什么呢?有以下四个功能:
1) 设置弹出框的大小,上图中也就是中间时间选择框的大小
2) 添加视图来改变展示内容的外观
3) 支持自定义视图的转场动画
4) 适配展示的外观当App环境改变时,比如屏幕旋转
那么UIKit怎么才会使用我们自定义的UIPresentationController呢?需要以下两个条件:
1)当你present一个控制器的时候,设置其modalPresentationStyle为custom,也就是指定present的类型为自定义的,不使用系统的
2)添加一个UIViewControllerTransitionDelegate代理,这个代理用来获取自定义的UIPresentationController
实现模态框的处理流程:
1)当present的时候,UIKit将会调用
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController?
来获取我们自定义的UIPresentationController