我有一个带有边框的自定义 UIButton 。当按钮对用户事件做出反应时,我希望layer.borderColor
与titleLabel
同步-即变为 Highlighted 或 Selected 。
有时这些事件会延迟播放动画,有时会立即播放。
例如: 点击并按住按钮-立即 释放按钮-带有动画
如何使按钮的边框复制相同的行为?如何跟踪 UIControlStates 之间的过渡?
即是否为边界设置动画取决于过渡:
Normal
-> Highlighted
-无动画
Highlighted
-> Normal
-带有动画
我如何检测到这种转变?
以下是按钮的代码,该代码无法解决将手指移出范围的事件,但效果很好:
import UIKit
final class BorderButton: UIButton {
override var isEnabled: Bool {
didSet {
updateBorderColor()
}
}
override var isSelected: Bool {
didSet {
updateBorderColor(animated: false)
}
}
override var isHighlighted: Bool {
didSet {
let animated = !isHighlighted
updateBorderColor(animated: animated)
}
}
override func tintColorDidChange() {
super.tintColorDidChange()
updateBorderColor()
}
private func updateBorderColor(animated: Bool = false) {
var color: UIColor = tintColor
if !isEnabled || tintAdjustmentMode == .dimmed {
color = dimmedTintColor()
} else if isHighlighted {
color = lightColor()
}
if animated {
let current = layer.borderColor ?? UIColor.clear.cgColor
let cgColor = color.cgColor
borderColorAnimation(from: current, to: cgColor, duration: 0.4)
} else {
layer.borderColor = color.cgColor
}
}
private func borderColorAnimation(from: CGColor, to: CGColor, duration: CFTimeInterval) {
let animation = CABasicAnimation(keyPath: "borderColor")
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
animation.fromValue = from
animation.toValue = to
animation.duration = duration
layer.add(animation, forKey: "borderColor")
layer.borderColor = to
}
private func lightColor() -> UIColor {
var hue: CGFloat = 0, saturation: CGFloat = 0, brightness: CGFloat = 0, alpha: CGFloat = 0
tintColor.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha * 0.2)
}
private func dimmedTintColor() -> UIColor {
var hue: CGFloat = 0, brightness: CGFloat = 0, alpha: CGFloat = 0
tintColor.getHue(&hue, saturation: nil, brightness: &brightness, alpha: &alpha)
return UIColor(hue: hue, saturation: 0, brightness: brightness, alpha: alpha)
}
}