Xcode/iOS更新后UIButton全局背景色影响导航栏按钮的修复求助
这问题我之前踩过类似的坑,iOS版本更新后UIKit的外观代理(UIAppearance)行为确实会有一些细微调整,导致原本不被影响的导航栏按钮现在继承了全局UIButton的背景色设置。给你几个靠谱的解决方案,按需求选就行:
方案1:针对性重置导航栏内按钮的外观(快速见效)
UIAppearance提供了appearanceWhenContainedInInstancesOfClasses:方法,能让我们给仅在特定容器内的控件单独设置外观,优先级会覆盖全局设置。刚好可以用这个来重置导航栏里的UIButton为透明:
// 先保留你的全局UIButton背景色设置 [[UIButton appearance] setBackgroundColor:[Helper getColor:self.application.color]]; // 专门给UINavigationBar内部的UIButton重置背景色为透明 [[UIButton appearanceWhenContainedInInstancesOfClasses:@[[UINavigationBar class]]] setBackgroundColor:[UIColor clearColor]];
这个方法精准度很高,只会影响导航栏里的按钮,其他页面的普通按钮依然保持你设置的全局背景色,亲测在iOS 15+版本都有效。
方案2:直接操作UIBarButtonItem的背景(适合系统导航按钮)
如果你的导航栏按钮都是系统默认的(比如UIBarButtonSystemItemDone这类),也可以直接针对UIBarButtonItem的外观重置背景:
// 全局设置普通UIButton的背景色 [[UIButton appearance] setBackgroundColor:[Helper getColor:self.application.color]]; // 清除UIBarButtonItem的背景图,恢复透明状态 [[UIBarButtonItem appearance] setBackgroundImage:nil forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; [[UIBarButtonItem appearance] setBackgroundImage:nil forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
不过要注意,如果你有自定义的导航栏按钮(比如用UIButton包装成UIBarButtonItem的情况),这个方法可能不生效,还是方案1更通用。
方案3:自定义按钮子类(长期维护首选)
如果你的项目有长期维护的需求,最好的方式是把业务按钮和导航栏按钮做类隔离:创建一个自定义UIButton子类(比如AppMainButton),只给这个子类设置全局外观,导航栏按钮继续用系统默认的UIButton或UIBarButtonItem。
步骤1:创建自定义按钮类
// AppMainButton.h #import <UIKit/UIKit.h> @interface AppMainButton : UIButton @end // AppMainButton.m #import "AppMainButton.h" @implementation AppMainButton @end
步骤2:设置自定义按钮的全局外观
// 在AppDelegate或启动配置代码里 [[AppMainButton appearance] setBackgroundColor:[Helper getColor:self.application.color]];
步骤3:替换项目中的普通按钮
把所有需要全局背景色的业务按钮,从UIButton换成AppMainButton,导航栏按钮保持不变。这样彻底隔离了两类按钮的外观设置,以后iOS再更新也不容易出现这类兼容性问题,代码结构也更清晰。
内容的提问来源于stack exchange,提问作者Mike Flynn

