如何限制.appearance不影响UIActivityViewController等系统视图控制器?
解决UIAppearance影响系统控制器控件的问题
方案1:自定义UIBarButtonItem子类,针对性设置样式
- 给需要自定义样式的按钮创建专属子类,仅对该子类应用UIAppearance设置,系统原生的UIBarButtonItem不受影响
- 示例代码:
// 定义自定义子类 class CustomStyledBarButtonItem: UIBarButtonItem {} // 仅对该子类设置样式 CustomStyledBarButtonItem.appearance().setTitleTextAttributes([ .font: UIFont(name: "YourCustomFont", size: 16)!, .foregroundColor: UIColor.white ], for: .normal)
- 后续自定义界面中使用
CustomStyledBarButtonItem替代原生UIBarButtonItem,系统控制器(如UIActivityViewController)内的按钮仍保持默认样式
方案2:临时重置样式,避免影响系统控制器
- 在弹出系统控制器前,临时保存当前UIBarButtonItem的样式,重置为系统默认,dismiss后恢复原样式
- 示例代码:
// 保存原样式 let originalTextAttributes = UIBarButtonItem.appearance().titleTextAttributes(for: .normal) // 临时重置为系统默认 UIBarButtonItem.appearance().setTitleTextAttributes(nil, for: .normal) // 弹出UIActivityViewController let activityVC = UIActivityViewController(activityItems: [/* 你的内容 */], applicationActivities: nil) present(activityVC, animated: true) { [weak self] in // 恢复原样式 UIBarButtonItem.appearance().setTitleTextAttributes(originalTextAttributes, for: .normal) }
- 优点:无需修改现有自定义按钮的代码;缺点:需注意多场景弹出系统控制器的情况,避免样式冲突
方案3:利用环境变量区分自定义与系统场景
- 定义自定义环境键,在自定义视图控制器中注入该环境值,通过读取环境值来控制按钮样式是否生效
- 示例代码:
// 定义自定义环境键 private struct CustomThemeEnvironmentKey: EnvironmentKey { static let defaultValue = false } extension EnvironmentValues { var useCustomBarButtonStyle: Bool { get { self[CustomThemeEnvironmentKey.self] } set { self[CustomThemeEnvironmentKey.self] = newValue } } } // 在自定义视图控制器中设置环境值 class CustomViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.environment(\.useCustomBarButtonStyle, true) } } // 自定义BarButtonItem中根据环境值设置样式 class ThemedBarButtonItem: UIBarButtonItem { override func didMoveToWindow() { super.didMoveToWindow() guard let window = window else { return } let shouldUseCustomStyle = window.environment(\.useCustomBarButtonStyle) if shouldUseCustomStyle { setTitleTextAttributes([ .font: UIFont(name: "YourCustomFont", size: 16)!, .foregroundColor: UIColor.white ], for: .normal) } else { setTitleTextAttributes(nil, for: .normal) } } }
- 优点:适合主题切换场景,可灵活控制样式生效范围;缺点:需要对现有控件进行一定改造
内容的提问来源于stack exchange,提问作者Andrei Herford
相关产品推荐
相关产品推荐

