自定义UI按钮选择的背景色未按预期工作(IOS/Swift)

自定义UI按钮选择的背景色未按预期工作(IOS/Swift),ios,swift,background,uibutton,Ios,Swift,Background,Uibutton,我有一个自定义的ui按钮类,其中该代码未按预期工作: override var isSelected: Bool { didSet { backgroundColor = isSelected ? UIColor.blue : UIColor.white } } 当我在代码中设置isSelected时,背景不会改变。。。它保持白色。我知道实际的布尔值isSelectedtrue/false实际上被正确地切换 didSet中

我有一个自定义的
ui按钮
类,其中该代码未按预期工作:

    override var isSelected: Bool {
        didSet {
            backgroundColor = isSelected ? UIColor.blue : UIColor.white
        }
    }
当我在代码中设置
isSelected
时,背景不会改变。。。它保持白色。我知道实际的布尔值
isSelected
true/false实际上被正确地切换

didSet中的代码正在执行(我已经通过打印调试进行了验证),但不知怎么的,后台没有被设置

有趣的是,我还以完全相同的方式重写了
ishighlight
方法,效果很好

下面是自定义按钮类的完整代码可以随意将其剪切/粘贴到您的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()

    }
}

谢谢你的帮助!我打赌这是一件非常愚蠢的事情!默普!:B

在阅读文档之后,我的理解是,在切换突出显示的值之后,它自动调用UIControl的更新/重画过程。对于isSelected切换,并非所有控件都能保证这一点。我认为UIButton就是其中之一

override func draw(_ rect: CGRect) {

    let path = getPath()

    fillColor.setFill()

    path.fill()

    strokeColor.setStroke()

    path.stroke()

  //ADD below line 

   self.backgroundColor = backgroundColor
}
更新的解决方案: 我错过的一件事是,无论何时点击按钮,isHighlighted的值都会变为true,点击结束时会变回false。因此,在您的情况下,只要点击结束,它就会变回
backgroundcolor=UIColor.white
。对于修复,我优先考虑突出显示的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()
        }
    }

阅读文档后,我的理解是,在切换突出显示的值后,它自动调用UIControl的更新/重画过程。对于isSelected切换,并非所有控件都能保证这一点。我认为UIButton就是其中之一

更新的解决方案: 我错过的一件事是,无论何时点击按钮,isHighlighted的值都会变为true,点击结束时会变回false。因此,在您的情况下,只要点击结束,它就会变回
backgroundcolor=UIColor.white
。对于修复,我优先考虑突出显示的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()
        }
    }

您将在运行时更新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()

}
不要忘记将“淡色”设置为“清除”,否则您会在按钮上看到一个蓝色的方点

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


您将在运行时更新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()

}
不要忘记将“淡色”设置为“清除”,否则您会在按钮上看到一个蓝色的方点

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



给出所选代码的设置位置。就像在您的视图或控制器中一样,感谢您花时间,但这不应该是必要的,因为“我知道实际的布尔值.isSelected true/false实际上正在正确切换。didSet中的代码正在执行(我已通过打印调试进行了验证),但不知何故背景没有设置。”你能试着在willSet方法中设置背景色吗?给出你设置背景色的代码。就像在您的视图或控制器中一样,感谢您花时间,但这不应该是必要的,因为“我知道实际的布尔值.isSelected true/false实际上正在正确切换。didSet中的代码正在执行(我已通过打印调试进行了验证),但不知何故背景没有设置。”你能试着用willSet方法设置背景色吗?谢谢你。。。我试过了,但没有成功。我理解这可能会起作用的概念,但这就是为什么我包含了这样一句话,“有趣的是,我也以完全相同的方式重写了isHighlighted方法,效果很好。”虽然这段代码可能会回答这个问题,提供有关此代码为什么和/或如何回答此问题的其他上下文可提高其长期价值感谢。。。我试过了,但没有成功。我理解这可能会起作用的概念,但这就是为什么我包含了这样一句话,“有趣的是,我也以完全相同的方式重写了isHighlighted方法,效果很好。”虽然这段代码可能会回答这个问题,提供有关此代码为什么和/或如何回答此问题的其他上下文,可提高其长期价值再次感谢您的努力。似乎不起作用。当然,这最终是我的错。:)如果您愿意,您可以将这个类直接剪切粘贴到您的Xcode中。您可能已经发现了您的问题。现在就去开会。将在30分钟后再次发布您是冠军。解开谜团。。。谢谢PS-您标记为“无效”的部分实际上仍然是相同的。另外,不需要使用“setNeedsDisplay()”。再次感谢您的努力。似乎不起作用。当然,这最终是我的错。:)如果您愿意,您可以将这个类直接剪切粘贴到您的Xcode中。您可能已经发现了您的问题。现在就去开会。将在30分钟后再次发布您是冠军。解开谜团。。。谢谢PS-您标记为“无效”的部分实际上仍然是相同的。此外,“setNeedsDisplay()”不是必需的。