自定义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()”不是必需的。