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)

用户喜欢...

使用光学传感器解决传感挑战

能够适应不断变化的应用要求的测量系统是首选,因为不断增长的成本压力需要较长的系统寿命和功能灵活性。开发此类系统的最有效方法是使用像PXI这样的软件定义的模块化架构。可以混合和...


使用DLP技术创建高分辨率自适应大灯

传统上,典型的汽车前照灯光束仅照亮车辆前方的物体,以提高驾驶员在低光照和恶劣天气条件下的可视性。低光束在车辆前方短距离照亮道路,而远光灯具有更长的范围和更宽的角度。这种...


使用原型套件简化能量收集设计

在使用设计之前,根据其环境条件,能量收集电路能够提供多少功率可能并不明显。 这会影响能量收集源和能量存储所需的尺寸和质量。 为了使设计进一步复杂化,诸如能量存储泄漏,稳压器...


使用Xilinx系统生成器实现简单的DDS

在本文中,我们将讨论使用Xilinx System Generator实现简单的直接数字频率合成器(DDS)。 System Generator是一个功能强大的工具,它将Xilinx FPGA设计过程与MATLAB的Simulink集成,后者使用高级描述轻松实...


可实现更佳充电灵活性的谐振式无线充电解决方案

可实现更佳充电灵活性的谐振式无线充电解决方案 谐振式无线充电技术利用磁共振在松散耦合的线圈之间传输功率,工作频率为 6.78 MHz。 对于要求充电时发射器与接收器线圈无需精准对准的应...


快速实现精度达 10 厘米的实时定位系统

无线电定位系统已成为几乎所有类型的移动设备和相关应用的标配功能。在众多无线电定位方法中,基于超宽带 (UWB) 射频通信的实时定位系统 (RTLS) 扮演了中枢角色,确保在 GPS 等更为人熟悉的...


如何为RF应用选择,使用和维护同轴连接器

无线电频率(RF)电路在有线和无线通信中正在激增,包括用于物联网(IoT)的Wi-Fi和各种无线技术。这些高频信号需要在系统,电路组件和子组件之间进行分配,而损耗或寄生辐射损耗最小。...


制造商和工程师:了解您的仪表放大器以实现准确的物联网数据采集

感知是物联网(IoT)和智能家居开始的地方,也是DIY爱好者,制造者甚至专业设计师遇到他们的第一个问题的地方。许多便宜的传感器,如加速计,力传感器,应变计和压力传感器都是围绕电...


为物联网程序存储器应用选择和使用正确的闪存技术

随着IoT节点变得越来越强大,处理需求可能会增加到需要完整的嵌入式操作系统(OS)(如Linux)才能正确管理所有运行任务的复杂性的水平。尽管将此代码存储在闪存microSDHC卡上很方便,但大...


使用RS-485和电流回路接口实现可靠的工业连接

尽管蓝牙,以太网和其他连接选项广泛普及并支持高数据速率,但工业应用设计人员仍然需要确保以最低的成本获得最可靠的连接。他们还必须在安装的连接选项基础范围内工作。 由于这些原...