ReplayKit中RPPreviewViewController的取消、保存按钮颜色如何修改?
RPPreviewViewController 自定义取消、保存按钮颜色的实现方法
为什么你之前的修改方式不生效
RPPreviewViewController是系统封装的独立控制器,内部的导航栏、按钮全部由系统托管,没有暴露任何公开接口让你直接拿到内部的UIBarButtonItem实例。你之前手动创建按钮后修改文字属性的方法,仅适用于自己实例化创建的按钮,对系统内部管理的按钮完全不生效。
最稳定无审核风险的实现方案
不需要硬遍历视图查找私有控件,利用UIBarButtonItem的全局外观配置机制,在展示预览控制器前临时设置按钮颜色,预览关闭后再恢复原始配置,全程使用公开API实现,不会因系统版本变动失效。
具体修改你现有的录屏停止逻辑:
- 在承载录屏逻辑的视图控制器类中,添加两个临时属性用于存储原始配置,避免退出预览时影响App其他页面的样式:
class RecordViewController: UIViewController { private let recorder = RPScreenRecorder.shared() // 临时存储预览展示前的全局按钮配置,用于退出时恢复 private var originalBarTint: UIColor? private var originalBarTitleAttr: [NSAttributedString.Key: Any]? } - 修改
stopRecorder方法,在present预览控制器前完成临时配置:func stopRecorder() { recorder.stopRecording { [unowned self] (preview, error) in guard let previewVC = preview else { return } // 记录原始全局按钮配置 self.originalBarTint = UIBarButtonItem.appearance().tintColor self.originalBarTitleAttr = UIBarButtonItem.appearance().titleTextAttributes(for: .normal) // 临时修改全局按钮颜色,系统预览控制器内的按钮会自动读取该配置 UIBarButtonItem.appearance().tintColor = .systemRed // 替换为你需要的按钮颜色 UIBarButtonItem.appearance().setTitleTextAttributes( [.foregroundColor: UIColor.systemRed], for: .normal ) previewVC.previewControllerDelegate = self previewVC.modalPresentationStyle = .fullScreen self.present(previewVC, animated: true, completion: nil) } } - 在已实现的
RPPreviewViewControllerDelegate回调中,恢复全局配置,避免影响其他页面:extension RecordViewController: RPPreviewViewControllerDelegate { func previewControllerDidFinish(_ previewController: RPPreviewViewController) { // 恢复原始全局按钮配置 UIBarButtonItem.appearance().tintColor = originalBarTint UIBarButtonItem.appearance().setTitleTextAttributes(originalBarTitleAttr, for: .normal) // 关闭预览控制器 previewController.dismiss(animated: true) } }
进阶:单独区分取消、保存按钮的颜色
如果需要给两个按钮设置不同样式(比如取消按钮为红色、保存按钮为绿色),可以在预览控制器展示完成后,通过公开的导航控制器API找到对应按钮实例修改,不需要递归遍历私有视图层级:
self.present(previewVC, animated: true) { // 延迟等待内部导航栏完成加载 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { // 找到预览控制器内部托管的导航控制器 if let navVC = previewVC.children.first(where: { $0 is UINavigationController }) as? UINavigationController, let navItem = navVC.navigationBar.items?.first { // 左侧为取消按钮,单独设置颜色 navItem.leftBarButtonItem?.tintColor = .systemRed // 右侧为保存按钮,单独设置颜色 navItem.rightBarButtonItem?.tintColor = .systemGreen } } }
避坑提醒
- 不要用递归遍历所有子视图的方式硬查找按钮:不同iOS版本下RPPreviewViewController的内部视图结构经常调整,这种写法很容易失效,甚至存在触发应用审核的风险。
- 不要在App启动时永久全局修改UIBarButtonItem的颜色配置,会覆盖全App所有页面的导航按钮样式,一定要在预览展示前临时设置、关闭后恢复。
内容的提问来源于stack exchange,提问作者tk97tk
相关产品推荐
相关产品推荐

