ARTICLE DETAIL

资讯详情

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

SwiftyPickerPopover 交互细节剖析:自动消失、外部点击关闭与背景变暗如何实现

SwiftyPickerPopover 交互细节剖析:自动消失、外部点击关闭与背景变暗如何实现 SwiftyPickerPopover 交互细节剖析自动消失、外部点击关闭与背景变暗如何实现【免费下载链接】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 开发中非常实用的弹出式选择器组件支持在 iPhone/iPad 的 iOS 9 系统上以系统原生 Popover 形态展示字符串选择器、日期选择器和倒计时选择器。除了选值本身它围绕如何关闭弹窗设计了三个值得深挖的交互细节定时自动消失、点击弹窗外部关闭、背景变暗聚焦。这篇文章就从源码角度逐一剖析这三个交互在 SwiftyPickerPopover 中分别如何实现并给出组合使用的示例。SwiftyPickerPopover 的三种关闭交互一表看懂先把三个交互对应的 API 和默认行为整理成一张表方便对照后面的源码分析交互方式对应 API默认行为定时自动消失disappearAutomatically(after:completion:)需主动调用到指定秒数后自动关闭点击外部关闭setOutsideTapDismissing(allowed:)默认允许背景变暗setDimmedBackgroundView(enabled:)默认关闭需显式开启三个 API 都遵循 SwiftyPickerPopover 经典的链式调用风格返回Self可以一路.下去写起来非常顺手。自动消失disappearAutomatically 定时关闭背后的机制弹窗出现几秒后自动消失在很多场景下都很重要比如倒计时提示、短暂的确认反馈。SwiftyPickerPopover 提供的入口是 AbstractPopover.swift 中的disappearAutomatically(after:completion:)。它的实现并不复杂但有一个很聪明的设计内部通过 DispatchQueueExtension.swift 中的cancelableAsyncAfter创建一个可取消的 DispatchWorkItem然后延迟执行disappear()。let p StringPickerPopover(title: 选择, choices: [选项A, 选项B, 选项C]) p.appear(originView: sender, baseViewController: self) p.disappearAutomatically(after: 3.0, completion: { print(弹窗已自动消失) })两个细节值得注意重复调用会取消上一次计时每次调用disappearAutomatically都会先dispatchWorkItem?.cancel()再重新调度。也就是说如果你希望用户每次滚动选择器就重新计时直接再次调用这个方法即可。交互可以续命源码中的redoDisappearAutomatically()就是干这个的——当用户滚动 UIPickerView 或点击 Clear 按钮时会自动重置计时器见 StringPickerPopoverViewController.swift。这意味着3 秒后自动消失实际上是用户停止操作 3 秒后才消失体验远比生硬的倒计时友好。点击外部关闭点一下空白处就收起弹窗这是 popover 交互的标配点击弹窗以外的区域弹窗自动收起。SwiftyPickerPopover 用setOutsideTapDismissing(allowed:)来控制默认是允许的。背后的实现依赖UIPopoverPresentationControllerDelegate。在 AbstractPickerPopoverViewController.swift 中控制器实现了两个关键方法popoverPresentationControllerShouldDismissPopover决定是否允许因点击外部而关闭直接读取isAllowedOutsideTappingDismissing的值返回。adaptivePresentationStyle返回.none这一步很重要它让 popover 在 iPhone 上也能保持气泡形态而不会被系统强制拉伸成全屏 modal。更有意思的是关闭后的处理外部点击触发关闭后系统会回调popoverPresentationControllerDidDismissPopover而 SwiftyPickerPopover 把它等同于点击了 Cancel 按钮见 StringPickerPopoverViewController.swift并执行 Cancel 对应的 action。这样点击外部和点 Cancel在业务逻辑上保持一致开发者不用分别处理两套回调。背景变暗用半透明遮罩把注意力拉回选择器当弹窗弹出时把背后的页面压暗能让用户视线自然聚焦到选择器上。SwiftyPickerPopover 用setDimmedBackgroundView(enabled: true)开启这个效果实现位于 AbstractPopover.swift 的addDimmedBackgroundViewIfNeeded创建一个覆盖UIScreen.main.bounds的全屏 UIView背景色设为黑色 0.5 透明度并打上accessibilityIdentifier DimmedView的标记把遮罩插入到baseViewController或其导航控制器视图的最上层弹窗本体不受影响。关闭时对应 removeDimmedView()先用 0.4 秒的动画把遮罩透明度渐变为 0再将其从父视图移除。这个淡出动画让关闭过程不生硬观感更顺滑。有一点要提醒遮罩是加在基础视图上、而不是弹窗内部的所以关闭弹窗时务必走disappear()/removeDimmedView()否则遮罩可能残留在页面上。源码里无论是 Done、Cancel 还是自动消失都会统一调用removeDimmedView()保证成对清理。组合实战三个交互一起用会怎样三个交互不是孤立的SwiftyPickerPopover 的 DemoDemo/SampleViewController.swift里就有现成的组合思路setOutsideTapDismissing(allowed: false)setDimmedBackgroundView(enabled: true)。这个组合的含义是背景压暗但不允许点击外部关闭。用户只能通过 Done / Cancel 按钮做决定适合必须明确选择的场景避免手滑点到空白处导致未选择就退出。再叠加自动消失一个完整的组合示例是这样let p StringPickerPopover(title: 请选择城市, choices: [北京, 上海, 广州]) .setOutsideTapDismissing(allowed: false) // 点击外部不关闭 .setDimmedBackgroundView(enabled: true) // 背景变暗聚焦选择 .setDoneButton(action: { popover, row, value in print(用户选择了\(value)) }) .setCancelButton(action: { _, _, _ in print(用户取消了) }) p.appear(originView: sender, baseViewController: self) p.disappearAutomatically(after: 8.0) // 8 秒后仍未操作则自动消失用户滚动选择器时计时器会自动重置配合setValueChange(action:)还能实时拿到当前选中值交互闭环非常完整。使用建议与避坑指南最后总结几条实战经验帮你少踩坑点击外部关闭默认开启如果弹窗里是重要表单记得用setOutsideTapDismissing(allowed: false)关掉它背景变暗默认关闭需要显式调用setDimmedBackgroundView(enabled: true)才会出现遮罩自动消失会覆盖上一次计时重复调用disappearAutomatically是安全的旧的延时任务会被取消不用担心弹出多个消失任务遮罩层级要心里有数它加在 base 视图上如果baseViewController在导航控制器里遮罩会加在导航控制器的 view 上而不是单个页面上外部点击 取消点击外部关闭会走 Cancel 的回调如果你的 Cancel 逻辑里有清空草稿之类的副作用外部点击也会触发需要留意是否符合预期。三个交互细节虽小却直接决定了弹窗组件的手感。理解了 SwiftyPickerPopover 的实现思路你也能在自己的项目中复刻出同样顺滑的弹出式选择器体验。【免费下载链接】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),仅供参考
返回列表