简体中文 | English | 开发文档 PRD | Development Document PRD
基于 CaiWanFeng/PiP 继续开发,完善:Yoroin。
增加悬浮窗后台保活、完全隐藏及与其他画中画并存保护。启用悬浮窗后,可帮助 ProMotion 设备和原本限制在 80Hz 左右的 App 获得最高 120Hz 的自适应刷新率表现。适配 iOS 15–iOS 27。
1.1.1 优化默认 VideoCall 方案:不再依靠悬浮窗固定请求 120Hz,而是保留 PiP 内容更新,在维持高刷效果的同时,修复部分锁 60 的游戏和 B 站弹幕卡顿问题,并优化直接隐藏后的自动熄屏行为。
默认 VideoCall 与仅 PiP 保活组合支持直接以 0.1pt 启动隐藏悬浮窗,并新增悬浮窗共存保护:其他 App 开启画中画时,可继续同时运行,避免我们的悬浮窗被挤掉或打断,不必因此反复重新开启。
此保护针对其他画中画的竞争,不代表 App 不会因内存压力、系统策略或其他异常被终止;兼容效果仍依赖系统及第三方 App。
实际刷新率及后台存活仍由设备、系统、前台 App 和资源状态共同决定,不代表固定 120Hz 或永久后台权限;60Hz 屏幕和 App 自身固定 60 帧的内容不能因此提升到 120 帧。
本项目是在原版 PiP 示例基础上继续开发的修改版,原作者为 CaiWanFeng。当前版本由 Yoroin 完善,主要增加了后台保活、悬浮窗高度调节(可完全隐藏悬浮窗)、iOS 26 液态玻璃 UI 适配、低版本 iOS 兼容处理和调试日志功能。
请注意:
- 本项目仅用于学习、研究和个人设备测试。
- 效果依赖系统画中画、设备刷新率能力和具体 App 的刷新率策略。
- 60Hz 设备或本身锁定 60Hz 的 App 无法通过本项目变成 120Hz。
- 后台保活并非系统级永久后台权限,仍可能受到内存压力、系统策略或其他画中画 App 的影响。
| 方案 | 隐藏能力 | 当前定位 | 注意事项 |
|---|---|---|---|
| 默认方案:VideoCall | 最低 0.1pt,可完全隐藏 | 日常推荐;与仅 PiP 保活组合使用本次内容更新、并存和熄屏优化 | |
| 兼容备选:PlayerLayer | 最低 1pt,侧边可能留有细线 | 保留原有兼容流程,不再作为解决默认方案弹幕卡顿的首选 | 无法完全隐藏;默认方案表现异常时可自行尝试 |
本次默认方案优化适用于 iOS 15–27 的 VideoCall 与仅 PiP 保活组合。音频强保活、锁屏音频增强及 PlayerLayer 保留兼容流程,不应视为相同实现。
- 帮助部分 ProMotion 设备和锁 80Hz 场景获得最高 120Hz 表现
- 默认悬浮窗支持后台保活、0.1pt 完全隐藏
- 悬浮窗共存保护:与其他画中画同时运行,避免被其他悬浮窗挤掉或打断
- 一键开启并隐藏;悬浮窗已开启时,一键调整为 0.1pt
- 自定义悬浮窗高度、侧边吸附框大小及高度记忆
- 支持开启或停止文字滚动,默认组合仍保留内容更新
- 帧率演示及 80Hz、120Hz 动画对比;刷新开关仅作用于 App 前台页面和动画
- 教程、默认方案升级演示及常见问题
- iPhone Duo 布局适配,iOS 26 及以上 Liquid Glass 风格和旧系统模糊背景
- 自动和手动缓存清理、正式版及 Beta 版更新检测
- 调试日志、有限的低频运行记录和系统诊断,辅助排查异常中断
- 日常推荐使用默认 VideoCall 与仅 PiP 保活。
- 直接隐藏:未开启悬浮窗时,点击“一键开启并隐藏”,以 0.1pt 启动。
- 可见悬浮窗:点击“开启悬浮窗”,按需要拖到侧边;点击“一键 0.1pt”或调节高度即可隐藏。
- 快捷指令需先在更多设置中开启并确认风险。iOS 26 及以上提供原生“打开并隐藏悬浮窗”动作;iOS 15–25 可手动导入,控制中心添加快捷指令需 iOS 18 及以上。
- 如遇异常,请附上 App 版本、系统版本、设备型号、底层与保活模式、复现步骤及诊断日志,在 GitHub Issues 提问,或在酷安评论区留言/私信。
其他兼容模式仍建议先开启并拖至侧边再缩小;PlayerLayer 最低 1pt。
本项目可作为已有悬浮窗 App 的底层方案参考,通常以默认 VideoCall 为主,不必照搬本 App 的首页与其他功能。
VideoCall 容器、高度调节仍采用 AVPictureInPictureVideoCallViewController、AVPictureInPictureController.ContentSource 和 preferredContentSize。1.1.1 默认 VideoCall 与仅 PiP 保活组合改为保留内容更新,不再沿用旧版悬浮窗固定请求 120Hz 的驱动方式。
以下旧用法在该默认组合中标记为不再使用,而非从整个工程统一删除:
将悬浮窗驱动的CADisplayLink.preferredFrameRateRange固定为minimum = maximum = preferred = 120将悬浮窗驱动的preferredFramesPerSecond固定为120使用帧率演示开关同步改变后台悬浮窗的刷新与播放策略
App 前台页面仍有独立的刷新请求,因此不能把 CADisableMinimumFrameDurationOnPhone 或全部 DisplayLink 一概标记为废弃。帧率演示开关不再控制后台悬浮窗。
画中画并存保护包含系统内部接口适配,并非 Apple 公开承诺的多 PiP 能力。不要将其写成公开 API 保证,也不要保证所有系统和第三方 App 都能共存;若用于上架产品,应单独评估私有接口的审核和兼容风险。
核心思路是创建一个透明的 AVPictureInPictureVideoCallViewController,通过 preferredContentSize 控制悬浮窗尺寸,再把自己的自定义 View 挂到这个 content view 里:
let contentController = AVPictureInPictureVideoCallViewController()
contentController.preferredContentSize = CGSize(width: 300, height: customHeight)
contentController.view.backgroundColor = .clear
contentController.view.isOpaque = false
let contentSource = AVPictureInPictureController.ContentSource(
activeVideoCallSourceView: sourceView,
contentViewController: contentController
)
let pipController = AVPictureInPictureController(contentSource: contentSource)后续调节高度时,同步更新 preferredContentSize 和你自己的内容 View 约束即可。需要视觉隐藏时,可以把高度调到很小,例如 0.1pt;如果不需要完全隐藏,也可以使用更保守的高度。
pip_swift/pip_swift/ViewController.swift:悬浮窗入口、两套底层创建、高度调节及保活策略pip_swift/pip_swift/PiPCoexistenceExperiment.swift:默认内容更新和画中画并存保护适配pip_swift/pip_swift/PiPShortcutIntents.swift:原生快捷指令入口pip_swift/pip_swift/FrameRateTestTabBarController.swift:App 前台帧率演示
旧版开发文档中的固定 120Hz 说明也需要按此范围同步修订,不应把“刷新内容”描述为跨系统保证有效的公开解锁 API。
项目导出的通用未签名 IPA 可通过以下工具自行签名安装:
- 牛蛙助手
- AltStore
- Sideloadly
- TrollStore 等其他支持自签的工具
请使用自己的 Apple ID、证书或设备环境完成签名安装。
- * 优化默认悬浮窗VideoCall方案,修复部分锁60的游戏和B站弹幕卡顿的问题
- * 新增悬浮窗共存保护,与其他画中画同时运行,避免被其他悬浮窗挤掉或打断
- * 修复 悬浮窗未拖至侧面而导致的无法熄屏
- 适配iPhone Duo
- 优化一键0.1pt:未开启时点击可直接启动隐藏悬浮窗,已开启时则调整高度;首页、快捷指令及URL入口保持一致,其他兼容模式保留原开启流程
- 精简快捷指令入口,仅保留打开并隐藏悬浮窗
- 优化 上次关闭时间 显示逻辑
- 减少仅PiP模式的音频预加载及后台页面刷新开销,内存紧张时清理未使用的音频和诊断缓存,不销毁悬浮窗
- 补充轻量运行记录和系统诊断,便于排查异常中断;关闭调试模式时仍保留有限的低频记录,不强行判断唯一原因
- 帧率演示的120Hz开关仅改变App前台页面和动画的刷新请求,关闭后按旧正式版请求最高80Hz,不再更改后台悬浮窗的刷新与播放策略;实际帧率仍由系统决定
- 新增默认悬浮窗方案升级演示,优化首次显示与重播动画,并同步常见问题说明
- 默认方案优化适用于iOS15-27的VideoCall与仅PiP保活组合;并存、熄屏及高刷效果仍依赖系统、设备与前台App,其他模式保留兼容流程
- 修复 iOS 15-iOS 18 悬浮窗被其他画中画应用挤掉后可能收不到通知的问题
- 优化 上次关闭时间 显示逻辑
- 新增锁屏音频增强 beta:亮屏时保持仅PiP,不影响音视频播放;熄屏后自动启用音频强保活,适合对锁屏后台保活有更高需求的用户;原有音频强保活仍保留
- 版本页新增手动清理缓存按钮,可查看释放的空间;长按可清空全部应用数据并重新进入首次使用流程
- 新增自动缓存清理,首次安装、覆盖更新和日常启动时会清理残留临时素材与过期缓存
- 清理并限制动态悬浮窗视频缓存,修复部分用户存储占用持续增长的问题
- 快捷指令改为默认关闭的风险功能,阅读并确认可能阻止自动熄屏后才会开放安装和使用
- 新增应用内版本检测,通过 GitHub Releases 公开接口读取最新正式版或 Beta 版版本号并与本机版本比较,不会自动下载或修改 App;支持跳过指定版本,下一版本发布前不再显示红点
- 帧率演示新增 80Hz 与 120Hz 同速动画对比,更直观展示 80Hz 的步进停顿与 120Hz 的连续移动,并保留上下滑动体验当前页面真实流畅度
- 新增首次启动动画与使用教程,通知权限会在引导结束后再申请
- 新增首页本次更新弹窗,可快速查看重点内容并进入完整更新日志
- 优化 iOS 26 及以上更新日志、常见问题等弹窗的 Liquid Glass 背景、圆角和滚动显示
- 优化中英文状态、运行时间和更新提示显示,修复部分页面文案不一致的问题
- 修复 iOS 26 以下切换深浅色模式后界面图标可能消失的问题
- 深浅色模式检测仅在 App 前台运行,进入后台后停止轮询
- 覆盖更新后默认关闭调试模式并清理历史诊断数据,避免后台监控和旧日志继续占用内存
- 保留 1.0.9 稳定版两套悬浮窗方案的核心创建、高度调节和 120Hz 作用路径,仅增加资源清理与问题诊断
- 注:此次更新重点解决问题,高刷作用字段回滚至1.0.7稳定版,解决部分iOS版本解锁120失效的问题;新增底层方案切换,解决b站弹幕和荒野乱斗卡顿,缺点无法完全隐藏最低1pt,原因,默认可隐藏悬浮窗底层会强拉120导致锁60的app卡顿,锁80的app不受影响
- 新增首页按钮 一键0.1pt 用于悬浮窗吸附后快速调节高度
- 优化悬浮窗的组件,避免0.1pt时屏幕出现两个白点(仅对iOS16+生效)
- 优化悬浮窗隐藏后的资源占用:当高度调至 0.1pt 时,暂停文字滚动和时钟刷新,减少长期后台挂载时的无效开销和发热
- 去除 后台中断通知beta 减少误报情况
- 优化深色模式切换逻辑,按钮移至首页
- 快捷指令尝试适配低版本iOS,如无法使用,请在更多设置-手动导入快捷指令使用
- 新增“底层切换”测试入口(日常用户请忽略):更多设置-底层切换-新方案。新方案仅用于解决因部分游戏和弹幕自身锁60而与120帧率不同步导致的卡顿,表现为b站弹幕一快一慢以及荒野乱斗大厅偶尔掉帧,新方案PlayerLayer参考悬浮时钟受底层限制最低1pt,无法完全隐藏,视觉上会有一条细线,默认方案VideoCall仍保留0.1pt隐藏能力,非必要请默认使用老方案
- 增加英文适配
- 简化调试模式,优化逻辑,不打开调试模式时完全停止日志记录减少性能开销
- 优化帧率检测逻辑
- 优化部分动画细节
- 默认启用原有文本悬浮窗、默认启用悬浮窗被挤通知(需要同意授权)、默认启用悬浮窗状态常驻、默认启用记忆悬浮窗高度
- 新增 手动填写高度
- 已知问题:直接用快捷指令一键开启悬浮窗隐藏会导致悬浮窗没有吸附到侧面,阻止熄屏,一般还是建议先启用悬浮窗,拖到侧面吸附后再点击一键0.1pt按钮
- 使用 Xcode 27 beta 构建,适配 iOS 15-iOS 27
- 新增悬浮窗时间、网速、帧率检测(因打开悬浮窗后全局默认120hz,帧率检测功能需要先临时关闭帧率演示的强制120hz开关)
- iOS 26 以下强制禁用时间悬浮窗,避免旧系统启用后导致全局120Hz失效;普通文本悬浮窗不受影响
- 首页更多设置新增 深色模式 开关,默认关闭时跟随系统设置,开启后固定使用深色模式
- 首页更多设置新增 悬浮窗被挤通知 和 后台中断通知 beta 两个独立开关;被挤通知用于其他画中画挤掉悬浮窗时实时提醒(一般只开这个就够用了)。后台中断通知 beta 默认关闭,通过定时轮询和预排本地通知辅助判断后台是否仍存活;频率主要影响异常发现速度和误报风险,不代表耗电量线性增加
- 优化首页布局稳定性,修复部分状态切换后页面轻微错位
- 新增系统快捷指令:打开并隐藏悬浮窗、打开悬浮窗、隐藏悬浮窗,便于放在控制中心一键操作;添加入口为长按控制中心-新增快捷指令-选中全局高刷,控制中心添加快捷指令仅支持 iOS 18+(如果屏幕上出现两个点是因为悬浮窗的关闭按钮没有隐藏,让悬浮窗恢复正常大小后点一下即可,下次会自动隐藏)
- 新增悬浮窗状态常驻开关,便于查看存活时间
- 适配深色模式桌面图标
- 优化悬浮窗停止流程
- 优化强制帧率演示页面描述,此开关目前开启和关闭都将影响悬浮窗的120hz功能
- 为了减少耗电量,经过实测对比后APP将默认启用为更为省电的仅PiP保活新方案,后台保活效果仍为显著,且解决了小部分场景下的音频冲突问题
- 可通过版本号-下方或首页查看当前保活模式
- 不再推荐使用老方案,如有需求可再自行前往调试模式-自由切换
- 首页新增悬浮窗状态检测,方便查看是否生效以及隐藏和是否被杀后台,点击可查看每次打开后的持续运行时间以及上次关闭时间,便于判断后台留存时间
- 首页停止滚动按钮移至二级菜单,防止误解
- 调试模式新增 保活方案切换 开关,可尝试切换为更省电的仅PiP保活方案,但后台留存率可能下降可能出现低版本兼容性问题,可自行选择
- 修复关闭悬浮窗后进入后台可能自动重新开启的问题
- 调试模式新增复制诊断日志功能,用于辅助排查耗电变化和推断后台保活中断时间段
- 修复iOS16部分用户卡顿的问题,修复iOS16部分用户相机可能导致的闪退问题以及自定义悬浮窗高度不生效的问题(感谢两位老铁的崩溃日志和测试)
- 修复部分用户反馈的音频冲突问题
- 优化旧版iOS系统的UI,未适配液态玻璃的组件采用高斯模糊
- 修复低版本iOS设备闪退问题,已在iOS15.8设备调试通过
- 对“滚动悬浮窗”增加默认记忆功能;首页新增 记忆悬浮窗高度 开关
- 尝试修复iOS16低版本无法打开悬浮窗的问题
- 调整自定义悬浮窗的最低值为0.1pt,可以做到完全隐藏悬浮窗
- 去除旋转窗口功能
- 增加自定义悬浮窗高度功能,可通过滑块无级调节
- 增加关闭/开启滚动功能
- 在原版基础上增加后台保活功能和修改悬浮窗大小
关于页提供“调试模式”开关。开启后可以复制最近运行日志,方便定位:
- 悬浮窗是否成功准备
- 系统是否允许开启画中画
- 前后台保活状态
- 音频中断与恢复
- 低版本 iOS 兼容分支状态
日志仅保存在本机,不会联网上传。用户主动点击复制后,才会写入剪贴板。
本项目以 CaiWanFeng/PiP 的原始 PiP Demo 为起点,由 Yoroin 持续开发与维护,逐步完善高刷辅助、后台保活、完全隐藏、画中画共存保护及界面与兼容适配。感谢 CaiWanFeng 提供原始示例。
- 原 Demo 项目:CaiWanFeng/PiP
- 原作者:CaiWanFeng
- 当前项目:Yoroin/GlobalRefresh-PiP
- 后续功能开发与维护:Yoroin
如果基于本项目继续开发、集成、分发或发布 App,请保留原始 Demo 作者 CaiWanFeng、后续开发者 Yoroin 及对应项目地址,明确所使用代码的来源。请勿将包含这些代码的项目声称为全部由自己原创。
本项目仅供学习和个人测试使用。使用者需要自行承担安装、签名、使用过程中的风险。请勿将本项目用于违反平台规则、商业侵权或其他不当用途。
