文章目录
-
- [SnipTrip 简介](#SnipTrip 简介)
- 体验亮点(从代码实现可见)
- 发热问题的核心成因
- 已落地的降温方案(当前代码状态)
-
- [方案 A:把高频刷新范围收缩到最小](#方案 A:把高频刷新范围收缩到最小)
- [方案 B:光晕分层 → 单层合成(防方框裁切)](#方案 B:光晕分层 → 单层合成(防方框裁切))
- [方案 C:DynamicLightOverlay 合成缓存](#方案 C:DynamicLightOverlay 合成缓存)
- [方案 D:缓存 CIContext,降低瞬时峰值](#方案 D:缓存 CIContext,降低瞬时峰值)
- 关键实现细节:为什么视觉没有变化
- 可选的后续优化方案
- 总结
SnipTrip 简介
SnipTrip 是一款 iOS 贴纸拼贴与画布编辑应用:从照片中生成贴纸、放置到 A4 画布上进行拖拽、缩放、旋转编辑,并支持导出与分享。界面采用液态玻璃质感与 Apple Intelligence 风格光晕,结合细腻的动态高光与触觉反馈,强调可交互区域与视觉层级。

左:深色模式下的彩虹光晕流动效果 | 右:浅色模式下的柔和光晕呼吸效果
体验亮点(从代码实现可见)
- 照片转贴纸 :通过 Vision 前景分割生成透明贴纸。
StickerService - A4 画布编辑 :画布尺寸 595×842,支持拖拽、缩放、旋转。
A4CanvasView - 高阶玻璃 UI :多层材质、动态高光、细腻边框。
ModernUI - 光晕动效 :流动 + 呼吸 + 色相漂移,强调交互区域。
ModernUI - 导出与分享 :处理后图片通过系统分享弹窗输出。
ContentView
发热问题的核心成因
发热并非来自单一函数,而是持续渲染路径的叠加:
-
高频重绘链路
全局时间驱动一旦扩散到视图树,会导致 SwiftUI 在 60/120Hz 下反复重算
body。 -
多层离屏合成
blur + blendMode(.plusLighter/.overlay/.screen)叠加会触发多次 GPU 合成。 -
峰值资源创建
CIContext频繁创建导致 CPU/GPU 峰值与内存抖动。
已落地的降温方案(当前代码状态)
方案 A:把高频刷新范围收缩到最小
思路 :保留光效时间驱动,但避免整棵 UI 树被每帧牵连。
实现:
- 使用
GlowClockDriver控制光效启停,不再让ContentView直接订阅刷新。 scenePhase进入后台或视图消失时立即停表,阻断不可见的持续刷新。
涉及文件:
SnipTrip/ContentView.swiftSnipTrip/SnipTripApp.swift
方案 B:光晕分层 → 单层合成(防方框裁切)
思路 :不改变视觉公式,只改变渲染路径。
实现:
对高成本光晕组件增加 rasterize 分支,并使用
padding → drawingGroup(opaque: false) → padding(-)
防止模糊被裁切形成"方框边缘"。
涉及组件:
AppleIntelligenceGlowAppleIntelligenceGlowLightVibrantGlowBorder
涉及文件:
SnipTrip/Views/ModernUI.swiftSnipTrip/ContentView.swiftSnipTrip/Views/A4CanvasView.swift
方案 C:DynamicLightOverlay 合成缓存
思路 :玻璃材质的动态高光继续存在,但渲染成本下降。
实现:
DynamicLightOverlay增加rasterize,并采用扩边合成策略。- 仅在
clipShape场景启用,避免可见方框。
涉及文件:
SnipTrip/Views/ModernUI.swift
方案 D:缓存 CIContext,降低瞬时峰值
思路 :贴纸处理高峰期降温,不影响最终画质。
实现:
StickerService 持有可复用 CIContext,避免重复创建上下文。
涉及文件:
SnipTrip/Services/StickerService.swift
关键实现细节:为什么视觉没有变化
- 动画公式不变:呼吸、旋转、色相漂移的计算保持原样。
- 视觉层未删除:光晕与高光仍完整保留。
- 只替换渲染路径:从多层离屏合成改为单层合成缓存。
因此"流动感/呼吸感/光晕强度"保持一致,同时功耗下降。
可选的后续优化方案
若需要进一步降低功耗,可按需求逐步启用:
-
TimelineView / KeyframeAnimator 驱动局部刷新
完全移除全局时间源,进一步降低级联重绘。
-
DynamicLightOverlay 降频
将
minimumInterval从1/30调低到1/45或1/60。 -
网格渲染按需创建
A4CanvasDottedGrid从"不可见仍渲染"改为条件创建。 -
减少模糊层级
在不影响观感的前提下减少 blur 层数与半径。
-
低电量/后台策略
低电量或
scenePhase != .active时自动冻结光效。
总结
SnipTrip 的"降温模型"并非关闭特效,而是:
- 控制刷新范围
- 减少 GPU 合成层数
- 降低峰值资源创建
在视觉体验不变的前提下,持续发热被显著抑制,交互手感保持细腻与顺滑。