iOS 26 Beta 4与iOS 18中UIBarButtonItem外观差异及保留iOS 18风格的实现方案问询
看起来你在iOS 26 Beta 4上碰到了导航栏按钮的样式回归问题,尤其是默认样式的意外变更和API弃用后的适配矛盾,我来帮你梳理几个可行的解决思路,帮你还原iOS 18及更早版本的清爽按钮风格:
一、解决Cancel按钮(.plain风格)在iOS26上的白背景/圆角问题
在iOS26 Beta版本中,系统似乎给.plain风格的UIBarButtonItem默认加上了容器化样式(白背景+圆角),这和之前纯文本无装饰的行为完全不符。要回到你想要的无背景、无圆角的纯文本样式,有两种稳妥的方案:
方案1:自定义UIButton包装成UIBarButtonItem(最灵活,完全可控)
直接用自定义UIButton来包装,彻底脱离系统默认样式的影响,跨版本表现一致:
// 替换原来的CancelButton创建逻辑 let cancelBtn = UIButton(type: .system) cancelBtn.setTitle("Close", for: .normal) cancelBtn.addTarget(self, action: #selector(cancelAndBack), for: .touchUpInside) // 强制设置无背景、无圆角 cancelBtn.backgroundColor = .clear cancelBtn.layer.cornerRadius = 0 // 匹配系统导航栏按钮的默认字体大小 cancelBtn.titleLabel?.font = UIFont.systemFont(ofSize: UIFont.buttonFontSize) // 转成UIBarButtonItem let cancelBarItem = UIBarButtonItem(customView: cancelBtn) self.navigationItem.leftBarButtonItem = cancelBarItem
方案2:利用UIAppearance全局修正(适合全App统一风格)
如果你的App里所有.plain风格的导航栏按钮都需要保持无背景,可以在App启动时或者当前ViewController的viewDidLoad中添加全局外观配置:
if #available(iOS 26.0, *) { // 针对导航栏内的.plain风格按钮,取消背景和圆角 UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationController.self]).backgroundColor = .clear UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationController.self]).cornerRadius = 0 }
注意:这个方案是全局生效的,如果有其他页面需要.plain按钮带背景,就不适合用这个方式。
二、解决Done按钮的样式一致性问题(替代弃用的.done风格)
iOS26中UIBarButtonItem.Style.done被官方弃用,推荐的.prominent风格是带蓝色背景的突出按钮,和原来.done的纯蓝色文本风格差异很大。要还原iOS18及更早版本的.done视觉效果,同样有两种方案:
方案1:用.plain风格+手动设置文本颜色(贴近系统API)
原来的.done风格本质就是蓝色文本的纯按钮,我们可以用.plain风格模拟,手动指定文本颜色:
let doneBarItem: UIBarButtonItem if #available(iOS 26.0, *) { doneBarItem = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(cancelAndBack)) // 手动设置文本为系统蓝色,还原原.done的视觉效果 doneBarItem.setTitleTextAttributes([.foregroundColor: UIColor.systemBlue], for: .normal) } else { doneBarItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(cancelAndBack)) } self.navigationItem.rightBarButtonItem = doneBarItem
方案2:和Cancel按钮一样用自定义UIButton包装(100%样式统一)
完全脱离系统API的样式约束,自己控制所有视觉细节:
let doneBtn = UIButton(type: .system) doneBtn.setTitle("Done", for: .normal) doneBtn.addTarget(self, action: #selector(cancelAndBack), for: .touchUpInside) doneBtn.backgroundColor = .clear doneBtn.layer.cornerRadius = 0 doneBtn.setTitleColor(.systemBlue, for: .normal) // 可选:给Done按钮加半粗体,贴近原.done风格的视觉权重 doneBtn.titleLabel?.font = UIFont.systemFont(ofSize: UIFont.buttonFontSize, weight: .semibold) let doneBarItem = UIBarButtonItem(customView: doneBtn) self.navigationItem.rightBarButtonItem = doneBarItem
三、关于iOS26 Beta的额外说明
你遇到的.plain按钮默认样式变更,大概率是Beta版本的临时调整或者bug,毕竟和之前的系统设计逻辑冲突。建议你:
- 查看Apple的iOS26 Beta发布说明,确认是否是已知问题
- 可以在Apple开发者论坛反馈这个行为回归,帮助官方在正式版中修正
- 暂时用上面的自定义方案做兼容,等正式版发布后再验证是否需要保留兼容代码
最后给你修改后的完整initView示例(采用自定义按钮方案)
func initView() { self.view.backgroundColor = .systemGray6 self.title = "Title" self.preferredContentSize = CGSize(width: 500, height: 600) // 自定义Cancel按钮 let cancelBtn = UIButton(type: .system) cancelBtn.setTitle("Close", for: .normal) cancelBtn.addTarget(self, action: #selector(cancelAndBack), for: .touchUpInside) cancelBtn.backgroundColor = .clear cancelBtn.layer.cornerRadius = 0 cancelBtn.titleLabel?.font = UIFont.systemFont(ofSize: UIFont.buttonFontSize) self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: cancelBtn) // 自定义Done按钮 let doneBtn = UIButton(type: .system) doneBtn.setTitle("Done", for: .normal) doneBtn.addTarget(self, action: #selector(cancelAndBack), for: .touchUpInside) doneBtn.backgroundColor = .clear doneBtn.layer.cornerRadius = 0 doneBtn.setTitleColor(.systemBlue, for: .normal) doneBtn.titleLabel?.font = UIFont.systemFont(ofSize: UIFont.buttonFontSize, weight: .semibold) self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: doneBtn) }
这个版本的代码在iOS18、iOS26 Beta上的表现完全一致,都是你想要的无背景、无圆角的纯文本/蓝色文本按钮。




