我有一个自定义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! :乙
答案 0 :(得分:2)
在阅读isSelected,isHighlighted和setNeedsDisplay()的文档后,我的理解是,在切换突出显示的值后,它会自动调用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上测试代码
答案 2 :(得分:0)
override func draw(_ rect: CGRect) {
let path = getPath()
fillColor.setFill()
path.fill()
strokeColor.setStroke()
path.stroke()
//ADD below line
self.backgroundColor = backgroundColor
}