ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SwiftyPickerPopover 源码解析:链式 Builder API 与 AbstractPopover 架构设计

SwiftyPickerPopover 源码解析:链式 Builder API 与 AbstractPopover 架构设计 SwiftyPickerPopover 源码解析链式 Builder API 与 AbstractPopover 架构设计【免费下载链接】SwiftyPickerPopoverA more convenient way to display a popover with a built-in picker, on iPhone/iPad of iOS9.项目地址: https://gitcode.com/gh_mirrors/sw/SwiftyPickerPopoverSwiftyPickerPopover 是一个面向 iOS 9 的开源弹窗组件它的核心能力是内置选择器Picker的 Popover让你几行代码就能在 iPhone / iPad 上弹出日期、字符串、倒计时等选择弹窗。本文对 SwiftyPickerPopover 源码进行解析重点拆解它极具代表性的链式 Builder API 与 AbstractPopover 架构设计为什么所有 setter 都能连续调用弹窗是怎么被造出来并展示的读完这篇文章你不仅能彻底理解这个库还能把这套架构思想用到自己的 Swift 项目里。一次调用背后链式 API 的直观体验先看 SwiftyPickerPopover 最经典的用法这是 README 中的基础示例DatePickerPopover(title: DatePicker) .setDoneButton(action: { _, selectedDate in print(selectedDate) }) .appear(originView: sender, baseViewController: self)短短三行创建 → 配置 → 展示。这就是链式 Builder API 的魅力——不需要记住十几个初始化参数需要什么就现场配置什么。这种fluent 风格在 DatePickerPopover.swift 中体现得淋漓尽致所有属性都是私有存储只通过setXxx()方法暴露。AbstractPopover所有弹窗的大脑与调度中心架构上最值得学习的是基类 AbstractPopover.swift。它扮演两个角色配置容器保存标题、尺寸、箭头方向、按钮参数、背景色等所有弹窗属性展示调度器负责加载 Storyboard、创建 NavigationController、配置 popoverPresentationController 并 present。一个非常巧妙的细节在初始化方法里——Storyboard 名称直接用类名推导storyboardName String(describing: type(of: self))也就是说DatePickerPopover会自动寻找DatePickerPopover.storyboard子类不需要重复实现加载逻辑。这也解释了为什么项目里有四份 Storyboard 文件DatePickerPopover.storyboard、StringPickerPopover.storyboard、ColumnStringPickerPopover.storyboard、CountdownPickerPopover.storyboard。链式 Builder API 的设计奥秘为什么.setSelectedDate(...)之后还能继续.setDoneButton(...)关键在于每个 setter 都返回Self而不是AbstractPopoverpublic func setSelectedDate(_ date: ItemType) - Self { self.selectedDate date return self }使用Self而非基类类型保证了链式调用的每一步都保留子类类型编译器才能识别后续的子类专属方法。这是 Swift 里实现 Builder 模式的标准姿势。更精细的设计是按钮配置的收敛。StringPickerPopover、DatePickerPopover、CountdownPickerPopover都有 Done / Cancel / Clear 三个按钮配置逻辑几乎相同于是统一抽成一个setButton(button:inout:title:font:color:action:)私有方法见 StringPickerPopover.swiftfunc setButton(button: inout ButtonParameterType, title: String? nil, font: UIFont? nil, color: UIColor? nil, action: ActionHandlerType?) - Self参数全部可选 只在非 nil 时覆盖默认值外部 API 干净内部实现也避免了三份重复代码。✅ 公共 API 只暴露语义化方法setDoneButton私有实现收敛重复逻辑——这是一条非常值得借鉴的接口设计准则。弹窗如何被创建与展示appear() 的完整旅程当调用appear(originView:baseViewController:)时AbstractPopover.swift 内部依次完成了这些工作解析 Bundle优先在主 Bundle 找自定义 Storyboard方便用户定制皮肤找不到再回退到框架 Bundle见 configureNavigationController实例化导航控制器从 Storyboard 取出初始UINavigationController设置modalPresentationStyle .popover锚定弹出位置用sourceViewsourceRect定位箭头支持barButtonItem和普通 View 两种原点桥接内容控制器把selfAbstractPopover注入内容 VC 的anyPopover属性可选的暗色遮罩setDimmedBackgroundView(enabled: true)时会添加一个半透明黑色遮罩层并置于最前present 圆角处理展示完成后若配置了cornerRadius则直接给弹出层的 superview 设置圆角。整个流程职责单一、步骤清晰堪称配置与展示分离的教科书式实现。ViewController 层AbstractPickerPopoverViewController 的双重职责与 AbstractPopover 配对的是 AbstractPickerPopoverViewController.swift。它的职责有两个① 属性 → 界面 的同步。refrectPopoverProperties()在viewWillAppear时被调用把 Popover 对象上的标题、尺寸同步到导航栏和preferredContentSize各子类再 override 它同步自己的专属属性如 StringPickerPopoverViewController.swift 中同步按钮标题、字体、tintColor 以及 picker 的选中行。② 让 Popover 在 iPhone 上也能工作。iOS 上 Popover 在 iPhone 默认会被适配成全屏而这里通过 delegate 强制保持弹窗形态open func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) - UIModalPresentationStyle { return .none }同时用popoverPresentationControllerShouldDismissPopover控制点击弹窗外区域是否关闭与setOutsideTapDismissing(allowed:)联动。四种弹窗类型一次看懂SwiftyPickerPopover 内置四种弹窗它们共享 AbstractPopover 的全部公共能力差别只在数据源与专属配置类型选择内容专属配置示例对应文件StringPickerPopover单列字符串setImageNames / setRowHeight / setDisplayStringForStringPickerPopover.swiftColumnStringPickerPopover多列字符串setFonts / setFontColors / setSelectedRowsColumnStringPickerPopover.swiftDatePickerPopover日期时间setDateMode / setMinimumDate / setMinuteIntervalDatePickerPopover.swiftCountdownPickerPopover倒计时时长setSelectedTimeIntervalCountdownPickerPopover.swiftStringPickerPopover 的效果如下顶部导航栏自带 Cancel / Done 按钮中间是 UIPickerView它甚至可以给每个选项配图setImageNames底层用 NSTextAttachment 实现图文混排让选项更直观DatePickerPopover 则直接封装 UIDatePicker支持.date、.time、.countDownTimer等多种模式还可以通过setClearButton一键清空选择细节设计自动消失、可清除与国际化三个细节体现了作者的工程素养自动消失disappearAutomatically(after:)借助 DispatchQueueExtension.swift 的cancelableAsyncAfter返回可取消的 DispatchWorkItem用户一旦拨动 pickerredoDisappearAutomatically()会取消旧任务、重新计时体验非常顺滑Clear 按钮setClearButton会在 choices 头部自动插入空值作为清空选项无需调用方手动维护国际化按钮默认标题走Done.localized工程内置 Base 与 ja 两套语言文件见 Base.lproj/Localizable.strings并支持用户通过自定义 Storyboard 覆盖界面。这套架构能给你什么启发纵观整个 SwiftyPickerPopover 源码最值得带走的四点是配置与展示分离一个配置对象AbstractPopover管数据一个展示对象ViewController管界面中间通过注入引用桥接扩展新弹窗类型时互不干扰Self返回类型的 Builder让子类链式调用不丢失类型信息是 Swift fluent API 的标准答案默认值兜底 可选参数所有配置都有合理默认值API 学习成本趋近于零Storyboard 按类名自动加载用命名约定替代繁琐注册新增一个弹窗类型只需写一个类 配一个同名 Storyboard。如果你正在开发类似的选择器、弹窗或表单类组件把 AbstractPopover.swift 和 AbstractPickerPopoverViewController.swift 这两份文件读透就是一次极佳的架构设计课。【免费下载链接】SwiftyPickerPopoverA more convenient way to display a popover with a built-in picker, on iPhone/iPad of iOS9.项目地址: https://gitcode.com/gh_mirrors/sw/SwiftyPickerPopover创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表