UIButton.normal状态异常:仅按压时显示图标问题
我用代码创建了如下SearchArea视图及其中的UIButton:
final class SearchArea: UIView { private let offset: CGFloat = 5 private(set) lazy var searchRequest = { let item = UITextField() item.backgroundColor = .systemBackground item.borderStyle = .roundedRect item.clearButtonMode = .always item.layer.cornerRadius = offset return item }() private(set) lazy var searchButton = { let item = UIButton() item.backgroundColor = .systemBlue item.layer.cornerRadius = offset item.setImage(UIImage(systemName: "magnifyingglass"), for: .normal) return item }() func setupView() { backgroundColor = .systemBackground let safeArea = self.safeAreaLayoutGuide addSubview(searchButton) searchButton.addConstraints( .alignTopWithTop(of: safeArea, const: offset), .alignBottomWithBottom(of: safeArea, const: offset), .alignTrailingWithTrailing(of: safeArea, const: offset), .setAspectWidth(ratio: 1) ) addSubview(searchRequest) searchRequest.addConstraints( .alignTopWithTop(of: safeArea, const: offset), .alignBottomWithBottom(of: safeArea, const: offset), .alignLeadingWithLeading(of: safeArea, const: offset), .alignTrailingWithLeading(of: searchButton, const: offset) ) } }
出现异常:按钮仅在被按压时显示图标,其余时间无图标。根据Apple官方文档,static var normal: UIControl.State是控件启用且未选中、未高亮的默认状态,设置该状态的图标应该正常显示,请问该如何解决?
问题原因
核心原因是系统默认的SF Symbol图标颜色与按钮背景色对比度极低,导致视觉上不可见。UIButton在normal状态下,imageView的tintColor默认为黑色(浅色模式)或白色(深色模式),当按钮背景色为.systemBlue时,浅色模式下黑色图标与蓝色背景的对比度不足,几乎无法分辨;而按压时按钮进入highlighted状态,系统会自动调整图标颜色,使其变得可见。
解决方法
1. 设置图标渲染模式并指定按钮 tintColor
创建图标时设置为模板渲染模式,再给按钮设置与背景色对比明显的tintColor:
private(set) lazy var searchButton = { let item = UIButton() item.backgroundColor = .systemBlue item.layer.cornerRadius = offset // 将图标设为可着色的模板模式 let searchImage = UIImage(systemName: "magnifyingglass")?.withRenderingMode(.alwaysTemplate) item.setImage(searchImage, for: .normal) // 设置图标颜色为白色,与蓝色背景形成高对比度 item.tintColor = .white return item }()
2. 直接指定不同状态的图标颜色(iOS 15+)
使用iOS 15新增的setImageTintColor(_:for:)方法,针对normal状态单独设置图标颜色:
private(set) lazy var searchButton = { let item = UIButton() item.backgroundColor = .systemBlue item.layer.cornerRadius = offset item.setImage(UIImage(systemName: "magnifyingglass"), for: .normal) // 给normal状态设置白色图标 item.setImageTintColor(.white, for: .normal) return item }()
3. 直接设置按钮 tintColor(最简方案)
无需修改图标渲染模式,直接给按钮设置tintColor,系统会自动将该颜色应用到normal状态的图标上:
private(set) lazy var searchButton = { let item = UIButton() item.backgroundColor = .systemBlue item.layer.cornerRadius = offset item.setImage(UIImage(systemName: "magnifyingglass"), for: .normal) item.tintColor = .white return item }()
内容的提问来源于stack exchange,提问作者Alexey_BH
相关产品推荐
相关产品推荐

