You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UIButton.normal状态异常:仅按压时显示图标问题

解决UIButton仅按压时显示图标的问题

我用代码创建了如下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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:22:56