You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

iOS 26 Beta 4与iOS 18中UIBarButtonItem外观差异及保留iOS 18风格的实现方案问询

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,毕竟和之前的系统设计逻辑冲突。建议你:

  1. 查看Apple的iOS26 Beta发布说明,确认是否是已知问题
  2. 可以在Apple开发者论坛反馈这个行为回归,帮助官方在正式版中修正
  3. 暂时用上面的自定义方案做兼容,等正式版发布后再验证是否需要保留兼容代码

最后给你修改后的完整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上的表现完全一致,都是你想要的无背景、无圆角的纯文本/蓝色文本按钮。

火山引擎 最新活动