close
当前位置: 物联网在线 > 技术文库 > ios >

使用 UIPresentationController 实现自定义弹窗

UIPresentationController 是 iOS8 新增的一个 API,可以用它实现自定义的弹窗。但 UIPresentationController 的使用门槛比较高,需要实现几个类和相关代理。 Presentr 让这一切变得简单,轻松实现自定义警告窗、菜单或其他任何弹窗。如下图:

使用 UIPresentationController 实现自定义弹窗

Presentr 实现弹窗

Presentr 提供了一个默认的弹窗类 AlertViewController,以下代码即可显示上面的弹窗:

let presenter = Presentr(presentationType: .Alert) presenter.transitionType = TransitionType.CrossDissolve let controller = Presentr.alertViewController(title: title, body: body) let cancelAction = AlertAction(title: "NO, SORRY! :scream:", style: .Cancel) { alert in print("CANCEL!!") } let okAction = AlertAction(title: "DO IT! ��", style: .Destructive) { alert in print("OK!!") } alertController.addAction(cancelAction) alertController.addAction(okAction) customPresentViewController(presenter, viewController: controller, animated: true, completion: nil)

要实现自定义的窗口,只需将上面的 AlertViewController 换成我们自己的窗口类即可,如下的 SomeViewController。

let alertController = SomeViewController() customPresentViewController(presenter, viewController: alertController, animated: true, completion: nil)

Presentr 提供了五种显示类型,如下

public enum PresentationType { case Alert case Popup case TopHalf case BottomHalf case Custom(width: ModalSize, height: ModalSize, center: ModalCenterPosition) }

通过 PresentationType.Custom 我们可自定义弹窗的大小

let width = ModalSize.Custom(size: 320) let height = ModalSize.Custom(size: 150) let center = ModalCenterPosition.Center //CustomOrigin(origin: CGPoint(x: 0, y: 100)) let customType = PresentationType.Custom(width: width, height: height, center: center) let customPresenter = Presentr(presentationType: customType) customPresenter.transitionType = .CrossDissolve Presentr 如何实现弹窗

Presentr 封装了 UIPresentationController,UIViewControllerTransitioningDelegate,UIViewControllerAnimatedTransitioning,类图如下:

使用 UIPresentationController 实现自定义弹窗

首先要清楚两个概念:当前的窗口为 presentingViewController,即将显示的窗口为 presentedViewController。 主要函数调用步骤:

在主窗口 UIViewController 中调用 customPresentViewController(presenter, viewController: alertController, animated: true, completion: nil)

Presentr: presentationControllerForPresentedViewController ,返回 PresentrController

Presentr: animationControllerForPresentedController

PresentrController: presentationTransitionWillBegin

PresentrController: frameOfPresentedViewInContainerView

PresentrController: containerViewWillLayoutSubviews

第一步是 Presentr 对 UIPresentationController 细节封装后提供的 UIViewController 的扩展函数。我们只需要写这行代码,剩下的步骤都由 Presentr 完成。这里,Presentr 将设置 PresentedView 的代理 —— transitioningDelegate = self 。

第二步和第三步都是 UIViewControllerTransitioningDelegate 协议的函数,由 Presentr 实现。第二步完成 UIPresentationController 的 子类 PresentrController 的初始化。在初始化创建一个黑色半透明背景视图,如下

init(presentedViewController: UIViewController, presentingViewController: UIViewController, presentationType: PresentationType, roundCorners: Bool, dismissOnTap: Bool) { self.presentationType = presentationType self.roundCorners = roundCorners self.dismissOnTap = dismissOnTap super.init(presentedViewController: presentedViewController, presentingViewController: presentingViewController) setupChromeView() } private func setupChromeView() { let tap = UITapGestureRecognizer(target: self, action: #selector(chromeViewTapped)) chromeView.addGestureRecognizer(tap) chromeView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.7) chromeView.alpha = 0 }

第三步是 PresentedView 出现时的动画效果。苹果自带的动画有从底向上弹窗、渐隐渐现、翻转,Presentr 实现了两个自定义的动画效果:从左往右或从右往左,从上往下。如果需要其他动画效果需要自己实现。

第四步,在 PresentedView 显示之前,添加半透明视图 chromeView 到 PresentrController 的 containerView 中,并添加 chromeView 的显示动画

override func presentationTransitionWillBegin() { chromeView.frame = containerView!.bounds chromeView.alpha = 0.0 containerView?.insertSubview(chromeView, atIndex: 0) if let coordinator = presentedViewController.transitionCoordinator() { coordinator.animateAlongsideTransition({ context in self.chromeView.alpha = 1.0 }, completion: nil) } else { chromeView.alpha = 1.0 } }

第五步,设置 PresentedView 的 frame 大小。


(责任编辑:ioter)

用户喜欢...

在智能手机上实现 1 Gbps RF 前端的简单方法

有人可能会问,我们为什么需要 1 Gbps 的下载速度?当前的下载速度还不够快吗?让我们面对现实吧:我们都讨厌看到手机上旋转的缓冲符号,而且我们总是想要更多数据。运营商也希望用户有...


云计算使用不断增长

究竟何为云计算?最简单的解释是,它是一种基于互联网的服务,提供对共享计算资源(例如存储、服务器、网络、应用、服务)的按需访问,还可将数据传输到连网的设备。使用这些服务,用...


直接数字合成器 (DDS) 的基础知识及其选择和使用方式

随着无线设备数量的激增,设计人员正在使用越来越复杂多变的波形,来满足应用在数据速率、干扰抑制、成本、封装和低功耗方面的要求。这些波形需要有稳定的射频源:可以根据需要进行调...


实现5G新型无线电大规模MIMO系统

大规模MIMO依赖于使用大量天线,是实现必要改进的关键技术,以证明从4G到5G无线网络的演进是合理的。 正在定义第五代(5G)无线接入网络,以满足2020年及以后的容量需求的持续增长,并解决...


使用无刷DC驱动器设计的六种奇怪方法

我已经知道了两个绝对真理。首先,无刷直流电机驱动器很酷。每个人都喜欢旋转电机的快感,无刷直流电机通过高速,高功率和高效率来提升令人惊叹的因素。其次,工程师喜欢有创意。有时...


应用最新的CAN总线增强功能,实现安全可靠的高速汽车通信

设计人员多年来一直依赖控制器局域网(CAN)来实现汽车各子系统和电子控制单元(ECU)之间的可靠通信。然而,随着机载网络节点的数量增加,所需的数据吞吐量以及对更低延迟和更高级安...


射频收发器在数字波束合成相控阵中实现强制杂散去相关性

在大型数字波束合成天线中,人们非常希望通过组合来自分布式波形发生器和接收器的信号这一波束合成过程改善动态范围。如果关联误差项不相关,则可以在噪声和杂散性能方面使动态范围提...


使用LDPC编码处理5G NR DL-SCH和UL-SCH传输块

该示例突出显示了用于5G NR下行链路和上行链路共享传输信道(DL-SCH和UL-SCH)的低密度奇偶校验(LDPC)编码链。 共享通道参数 该示例使用DL-SCH来描述处理,其也适用于UL-SCH。 选择在下行链路共...


使用毫米波雷达套件快速开发精密目标检测设计

设计人员在设计运动传感器时面临着持续的竞争压力。传感器不仅要体积更小、更精确,并且还要在智能建筑、工厂自动化、交通运输和无人机等多种行业应用中具有更远的检测范围。虽然毫米...


Arduino 环境中的 FPGA:使用 Alorium 的 Snō 模块支持预配置和定制 IP

当固件在微控制器或微处理器上的运行速度过慢时,现场可编程门阵列 (FPGA) 可解决实时嵌入式设计的硬件问题。同时,FPGA 还具有外设灵活性。然而,要使用 FPGA,设计工程师就需要学习全新的...