自定义UIButton选择的背景颜色不能按预期工作(IOS / Swift)

时间:2018-04-10 04:33:00

标签: ios swift background uibutton

我有一个自定义UIButton类,此代码无法按预期运行:

    override var isSelected: Bool {
        didSet {
            backgroundColor = isSelected ? UIColor.blue : UIColor.white
        }
    }

当我在代码中设置isSelected时,背景不会改变......它会保持白色。我知道实际的布尔值isSelected true / false实际上是正确切换的。

didSet IS中的代码正在执行(我已经通过打印调试验证了),但不知道背景是否已经设置。

有趣的是,我也以完全相同的方式覆盖了isHighlighted方法,效果很好。

以下是自定义按钮类的完整代码。 随意剪切/粘贴到你的XCODE中并随之玩耍

import UIKit

@IBDesignable
class PlusMinusButton: UIButton {

    @IBInspectable
    var highlightColor: UIColor = .yellow { didSet { setNeedsDisplay() } }

    @IBInspectable
    var fillColor: UIColor = .yellow { didSet { setNeedsDisplay() } }

    @IBInspectable
    var strokeColor: UIColor = .yellow { didSet { setNeedsDisplay() } }

    @IBInspectable
    var plusOrMinus: Bool = true { didSet { setNeedsDisplay() } }


    func getPath() -> UIBezierPath {

        let G = bounds.width / 5

        let path = UIBezierPath()

        switch plusOrMinus {

        case true:

            let startPoint = CGPoint(x:2*G,y:G)
            path.move(to: startPoint)
            path.addLine(to: CGPoint(x:2*G,y:2*G))
            path.addLine(to: CGPoint(x:G,y:2*G))
            path.addLine(to: CGPoint(x:G,y:3*G))
            path.addLine(to: CGPoint(x:2*G,y:3*G))
            path.addLine(to: CGPoint(x:2*G,y:4*G))
            path.addLine(to: CGPoint(x:3*G,y:4*G))
            path.addLine(to: CGPoint(x:3*G,y:3*G))
            path.addLine(to: CGPoint(x:4*G,y:3*G))
            path.addLine(to: CGPoint(x:4*G,y:2*G))
            path.addLine(to: CGPoint(x:3*G,y:2*G))
            path.addLine(to: CGPoint(x:3*G,y:G))
            path.addLine(to: startPoint)

        case false:

            let startPoint = CGPoint(x:G,y:3*G)

            path.move(to: startPoint)
            path.addLine(to: CGPoint(x:4*G,y:3*G))
            path.addLine(to: CGPoint(x:4*G,y:2*G))
            path.addLine(to: CGPoint(x:G,y:2*G))
            path.addLine(to: startPoint)

        }

        path.close()

        return path

    }

    // see how is method is exactly the same as the next?  weird, huh?
    override var isHighlighted: Bool {
        didSet {
            backgroundColor = isHighlighted ? highlightColor : UIColor.white
        }
    }

    override var isSelected: Bool {
        didSet {
            print("This line of code is executed!!")
            backgroundColor = isSelected ? UIColor.blue : UIColor.white
        }
    }

    override func draw(_ rect: CGRect) {

        let path = getPath()

        fillColor.setFill()

        path.fill()

        strokeColor.setStroke()

        path.stroke()

    }
}

感谢您的帮助!我打赌它真的很蠢! MERP! :乙

3 个答案:

答案 0 :(得分:2)

在阅读isSelectedisHighlightedsetNeedsDisplay()的文档后,我的理解是,在切换突出显示的值后,它会自动调用UIControl的更新/重绘过程。对于isSelected切换,不保证所有控件都可以。我认为UIButton就是其中之一。

更新解决方案 我错过的一件事是,无论何时你按下你的按钮值isHighlighted变为true并且当tap结束变为false时。因此,在您的情况下,无论何时结束,它都会更改回backgroundcolor = UIColor.white。为了解决这个问题,我优先选择highLighted bool,然后将isSelected bool设置为背景颜色。请检查以下代码

override var isHighlighted: Bool {
        didSet {
            backgroundColor =  isHighlighted ? highlightColor : (isSelected ? UIColor.blue : UIColor.white)
        }
    }

override var isSelected: Bool {
        didSet {
            backgroundColor = isSelected ? UIColor.blue : UIColor.white
            setNeedsDisplay()
        }
    }

<强>无效:

    override var isSelected: Bool {
        didSet {
            backgroundColor = isSelected ? UIColor.blue : UIColor.white
            setNeedsDisplay()
        }
    }

答案 1 :(得分:2)

您将在运行时更新ui组件。我想你需要在运行时在主线程上执行代码。试试这个:

override var isSelected: Bool {

    didSet {

        print("This line of code is executed!!")

        DispatchQueue.main.async {

            self.backgroundColor = self.isSelected ? UIColor.blue : UIColor.white
        }
    }
}

override func draw(_ rect: CGRect) {

    self.tintColor = .clear

    let path = getPath()

    fillColor.setFill()

    path.fill()

    strokeColor.setStroke()

    path.stroke()

}

不要忘记将tintColor设置为清除,否则您会在按钮上看到蓝色方形点。

工作...!使用Swift 4.0.2在Xcode 9.3上测试代码

OutPut colors for buttons

答案 2 :(得分:0)

override func draw(_ rect: CGRect) {

    let path = getPath()

    fillColor.setFill()

    path.fill()

    strokeColor.setStroke()

    path.stroke()

  //ADD below line 

   self.backgroundColor = backgroundColor
}