setTitleColor 不适用于 .disabled 状态下的自定义 UIButton

问题描述 投票:0回答:3

我有一个表格来收集基本的用户信息。窗体上有一个“继续”按钮,根据它是否处于

.enabled
.disabled
状态具有不同的外观。

.enabled
状态格式与
setTitleColor
方法一起工作。但是当我为
setTitleColor
状态执行
.disabled
时,按钮文本颜色变为与我想要的颜色不同的颜色。这是怎么回事?

我有一个

CustomButton
UIButton
子类,当其上方的文本字段为空时,它会将其状态更改为
.disabled
。然后我调用一个函数来执行一些自定义格式设置,为
.disabled
按钮提供带有浅灰色文本的中灰色背景。

class CustomButton: UIButton {

    // Format a button with filled background
    // Default button text color to white if no parameter is provided
    func configFilledButton(color: UIColor, textColor: UIColor? = UIColor.white) {

        self.titleLabel?.textColor = textColor
        self.backgroundColor = color
        self.setTitleColor(color, for: .disabled)

    } // close configFilledButton


    // Call this function to toggle the Continue button state to disabled
    func toggleEnabledState(isEnabled: Bool) {
    
        if isEnabled == false {
                    
            let newColor = UIColor(named: K.BrandColors.greyMedium)!
            
            self.configFilledButton(
                color: newColor, 
                textColor: UIColor(named: K.BrandColors.greyLight))

     } // close toggleEnabledState 

} // close CustomButton

当我运行代码来禁用按钮时,按钮背景会更改为正确的颜色,但标题文本会更改为我未设置的颜色(我假设它为禁用按钮使用了一些默认颜色)。我验证了我在 Assets 文件夹中使用的颜色在我的常量

K.brandColors
结构中正确命名和引用。

知道为什么

setTitleColor
似乎不适用于
.disabled
状态吗?

ios swift formatting uibutton swiftui-state
3个回答
0
投票

您可以通过使用

.normal
/
.highlighted
/
.disabled
状态...然后覆盖
isEnabled
来处理背景颜色变化,从而节省大量工作:

class CustomButton: UIButton {
    
    // these will be set by configure()
    private var bkgEnabled: UIColor = .white
    private var bkgDisabled: UIColor = .black

    override init(frame: CGRect) {
        super.init(frame: frame)
        // configure with defaults
        self.configure()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        // configure with defaults
        self.configure()
    }
    
    // Format a button...
    // Each parameter has a "default" value
    func configure(titleNormal: UIColor? = .white,
                   titleHighlighted: UIColor? = .lightGray,
                   titleDisabled: UIColor? = .darkGray,
                   bkgEnabled: UIColor? = .red,
                   bkgDisabled: UIColor? = .lightGray) {
        
        self.setTitleColor(titleNormal, for: .normal)
        self.setTitleColor(titleHighlighted, for: .highlighted)
        self.setTitleColor(titleDisabled, for: .disabled)
        self.backgroundColor = self.isEnabled ? bkgEnabled : bkgDisabled

        // update background color properties
        self.bkgEnabled = bkgEnabled!
        self.bkgDisabled = bkgDisabled!
    }

    // this will set the background color, based on Enabled / Disabled state
    override var isEnabled: Bool {
        didSet {
            self.backgroundColor = isEnabled ? bkgEnabled : bkgDisabled
        }
    }
    
}

这是一个示例控制器......它将创建两个自定义按钮:

  • 顶部按钮 - “按钮 A” - 将使用默认颜色值
  • 我们将为底部按钮设置自定义颜色值 - “按钮 B”
  • 点击顶部按钮将切换
    .isEnabled
    底部按钮的状态

控制器类:

class ViewController: UIViewController {
    
    let customButtonA = CustomButton()
    let customButtonB = CustomButton()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        customButtonA.translatesAutoresizingMaskIntoConstraints = false
        customButtonB.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(customButtonA)
        view.addSubview(customButtonB)

        NSLayoutConstraint.activate([
            customButtonA.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            customButtonA.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -80.0),

            customButtonB.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            customButtonB.topAnchor.constraint(equalTo: customButtonA.bottomAnchor, constant: 40.0),
        ])

        customButtonA.setTitle("Toggle enabled/disabled", for: [])
        customButtonB.setTitle("Enabled", for: [])
        
        customButtonA.addTarget(self, action: #selector(btnATapped(_:)), for: .touchUpInside)
        customButtonB.addTarget(self, action: #selector(btnBTapped(_:)), for: .touchUpInside)
        
        customButtonB.configure(titleNormal: .red, titleHighlighted: .green, titleDisabled: .black, bkgEnabled: .yellow, bkgDisabled: .gray)
        
    }
    @objc func btnATapped(_ sender: UIButton) {
        print("Toggling .isEnabled of button B")
        customButtonB.isEnabled.toggle()
        let t: String = customButtonA.isEnabled ? "Enabled" : "Disabled"
        customButtonB.setTitle(t, for: [])
    }
    @objc func btnBTapped(_ sender: UIButton) {
        print("Button B tapped")
    }

}

class CustomButton: UIButton {
    
    // these will be set by configure()
    private var bkgEnabled: UIColor = .white
    private var bkgDisabled: UIColor = .black

    override init(frame: CGRect) {
        super.init(frame: frame)
        // configure with defaults
        self.configure()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        // configure with defaults
        self.configure()
    }
    
    // Format a button...
    // Each parameter has a "default" value
    func configure(titleNormal: UIColor? = .white,
                   titleHighlighted: UIColor? = .lightGray,
                   titleDisabled: UIColor? = .darkGray,
                   bkgEnabled: UIColor? = .red,
                   bkgDisabled: UIColor? = .lightGray) {
        
        self.setTitleColor(titleNormal, for: .normal)
        self.setTitleColor(titleHighlighted, for: .highlighted)
        self.setTitleColor(titleDisabled, for: .disabled)
        self.backgroundColor = self.isEnabled ? bkgEnabled : bkgDisabled

        // update background color properties
        self.bkgEnabled = bkgEnabled!
        self.bkgDisabled = bkgDisabled!
    }

    // this will set the background color, based on Enabled / Disabled state
    override var isEnabled: Bool {
        didSet {
            self.backgroundColor = isEnabled ? bkgEnabled : bkgDisabled
        }
    }
    
}

看起来像这样开始:

点击底部按钮(突出显示)时:

在点击顶部按钮禁用底部按钮后:


0
投票

self.setTitleColor(color, for: .disabled) 是错误的。请使用 self.setTitleColor(textColor, for: .disabled)

"当按钮进入禁用状态时,alpha 值将应用于文本和背景。如果您希望文本颜色在没有 alpha 的情况下保持纯色,请使用 .disabled 状态设置文本颜色。否则,使用 .normal文本颜色的状态。”


0
投票

如果

UIButton
风格设置为
Plain
setTitleColor
等功能不会影响外观。在 Storyboard 中,转到 Attributes Inspector 并将 Style 属性从
Plain
更改为
Default
以解决问题。

感谢所有回复的人,你帮助我理解了问题出在我的故事板而不是代码!我在这里找到了解决方案:Setting the background of an UIButton programmatically not working

编辑:另请参阅 DonMag 的详细答案和评论主题

© www.soinside.com 2019 - 2024. All rights reserved.