导航栏自定义按钮图片无法通过Tint方法变色的问题咨询
问题根源与修复方案
为什么导航栏按钮的tint方法失效?
看了你的代码,发现两个核心问题:
- 图片覆盖问题:你先给按钮设置了调整尺寸后的图片,但随后调用
tint方法时,把原始尺寸的图片设为template模式后赋值给了imageView,直接覆盖了之前的resize图片。这不仅会导致图标尺寸不对,还因为导航栏的布局特性,让tint效果看起来“失效”。 - tintColor的优先级问题:你直接设置
imageView的tintColor,但UIButton本身的tintColor优先级更高,而且导航栏的默认tintColor可能会对自定义视图产生间接影响,导致你的设置被覆盖。
修复方案
方案一:调整图片处理流程(推荐)
在设置按钮图片前,就完成尺寸调整和template模式的设置,同时直接给按钮设置tintColor(比设置imageView更可靠):
let dashboardButton = UIButton(type: .custom) // 先获取原始图片并处理 if let dashboardButtonImage = UIImage(named: "example image name") { // 调整尺寸 + 设置为template模式 let processedImage = dashboardButtonImage .imageResize(sizeChange: CGSize(width: 20, height: 20)) .withRenderingMode(.alwaysTemplate) // 设置到按钮 dashboardButton.setImage(processedImage, for: .normal) // 直接给按钮设置tintColor,imageView会自动继承 dashboardButton.tintColor = .red } // 剩余设置保持不变 dashboardButton.contentHorizontalAlignment = .fill dashboardButton.contentVerticalAlignment = .fill dashboardButton.imageView?.contentMode = .scaleAspectFit dashboardButton.frame = CGRect(x: 0, y: 0, width: 30, height: 30) dashboardButton.addTarget(self, action: #selector(ExampleViewController.goToDashboard), for: .touchUpInside) let dashboardItem = UIBarButtonItem(customView: dashboardButton) self.navigationItem.setRightBarButtonItems([dashboardItem], animated: false)
方案二:修改你的tint方法适配按钮
如果想保留原有的tint方法逻辑,可以修改它直接操作UIButton,确保处理的是按钮当前的图片:
/// 给UIButton的图标设置tint颜色 /// - Parameters: /// - button: 目标按钮 /// - colour: 要设置的颜色,nil则恢复原始渲染模式 func tint(button: UIButton, with colour: UIColor?) { guard let currentImage = button.image(for: .normal) else { return } if let colour = colour { let templateImage = currentImage.withRenderingMode(.alwaysTemplate) button.setImage(templateImage, for: .normal) button.tintColor = colour } else { let originalImage = currentImage.withRenderingMode(.automatic) button.setImage(originalImage, for: .normal) } }
调用时改成:
let dashboardButton = UIButton(type: .custom) if let dashboardButtonImage = UIImage(named: "example image name") { let resizedImage = dashboardButtonImage.imageResize(sizeChange: CGSize(width: 20, height: 20)) dashboardButton.setImage(resizedImage, for: .normal) // 调用修改后的tint方法 style.tint(button: dashboardButton, with: .red) } // 剩余设置不变...
额外说明
- 如果你的图标是多色的,不要使用
.alwaysTemplate模式,这种模式会把所有非透明像素统一渲染为tintColor; - 自定义导航栏按钮时,直接设置按钮的
tintColor比设置imageView更稳定,因为按钮的状态(如高亮、选中)会自动继承这个颜色,避免状态切换时颜色异常。
内容的提问来源于stack exchange,提问作者StartPlayer
相关产品推荐
相关产品推荐

