自定义UIButton是选定的背景颜色,未按预期工作(IOS / Swift)

pbwdgjma  于 2022-11-19  发布在  iOS
关注(0)|答案(4)|浏览(127)

我有一个自定义的UIButton类,其中的代码没有按预期工作:

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

当我在代码中设置isSelected时,背景不会改变...它保持白色。我知道实际的布尔值isSelected true/false实际上被正确地切换。
didSet内部的代码正在执行(我已经用打印调试验证过了),但是不知何故,后台没有被设置。
有趣的是,我还以完全相同的方式重写了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!:B

avwztpqn

avwztpqn1#

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

**更新的解决方案:**我遗漏了一件事,那就是,每当你点击你的isHighlighted按钮时,它的值会变成true,而当点击结束时,它会变回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()
        }
    }
gajydyqb

gajydyqb2#

你将在运行时更新一个用户界面组件。我认为你需要在运行时在主线程上执行代码。试试看:

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设置为clear,否则您会在按钮上看到一个蓝色方点。
正在工作...!已在Xcode 9.3和Swift 4.0.2上测试代码

3duebb1j

3duebb1j3#

override func draw(_ rect: CGRect) {

    let path = getPath()

    fillColor.setFill()

    path.fill()

    strokeColor.setStroke()

    path.stroke()

  //ADD below line 

   self.backgroundColor = backgroundColor
}
kd3sttzy

kd3sttzy4#

这里有一个解决方案。.toggle()从Swift 4.2开始可用

class Button: UiButton {
    override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        isSelected.toggle()
        backgroundColor = isSelected ? .blue : .red
    }
}

相关问题