如何在自定义 UIButton 中实现 .isHighlighted 动画?
How to achieve .isHighlighted animation in a Custom UIButton?
序言(实际问题的代码后向下翻页):
我有一个自定义 UIButton
class,其中我用以下行为替换了普通的 UIButton
isHighlighted
动画行为:
当用户的手指实际放在按钮上时(即突出显示按钮),按钮周围会出现一个描边轮廓(方形边框)。当他们不再触摸按钮时,轮廓就会消失。
此外,我已将正常的 isSelected
行为(背景变为蓝色)替换为:
绘制了一个与isHighlighted
相同的轮廓,只是稍微粗一点,并且在isSelected = true
时一直存在,而在isSelected = false
时不存在。
这行得通,我就是这样做的:
import UIKit
class CustomButton: UIButton {
// BUTTON TYPES:
// Gorsh, enums sure would be swell here. :T
// 1 : plus
// 2 : minus
// 3 : etc etc....
@IBInspectable
var thisButtonsType: Int = 1 { didSet { setNeedsDisplay() } }
@IBInspectable
var fillColor: UIColor = .black { didSet { setNeedsDisplay() } }
@IBInspectable
var strokeColor: UIColor = .black { didSet { setNeedsDisplay() } }
override var isHighlighted: Bool {
didSet {
setNeedsDisplay()
}
}
override func draw(_ rect: CGRect) {
let unitOfMeasure = bounds.width / 5
// draw outline in case we are selected / highlighted
if (isSelected || isHighlighted) {
let tempPath = BezierPathFactory.outline(totalWidth: bounds.width)
if (isSelected) {tempPath.lineWidth = 4.0}
strokeColor.setStroke()
tempPath.stroke()
}
// initialize path object
var path = UIBezierPath()
// get the path corresponding to our button type
switch thisButtonsType {
case 1:
path = BezierPathFactory.plus(gridSpacing: unitOfMeasure)
case 2:
path = BezierPathFactory.minus(gridSpacing: unitOfMeasure)
default: print("hewo!")
}
fillColor.setFill()
path.fill()
}
}
再一次,该代码有效,但是...
我最想要的是,如果是高亮的边框轮廓会在触摸结束后逐渐消失。
注意:如果您想知道为什么我会这样做...我计划实现许多不同的按钮类型...它们上面都有不同的图标 "printed"...但是我希望他们都遵循这些基本行为。其中只有几个 "toggle" 按钮会被选中,因此高亮淡入淡出是有用的。
我已经知道如何制作动画...但我只是在绞尽脑汁思考如何在这种情况下制作动画。
我希望我能得到 UIButton 源代码。
有没有一种方法可以在不完全改变设计模式的情况下,相对简单地将淡入淡出动画添加到我的上述代码中?我是否必须开始使用核心图形的一些其他功能,如图层?
谢谢!
您可以执行以下操作:
- 创建
UIButton
的子层 class,它添加和管理 class CAShapeLayer
的子层,用于按钮的轮廓。
- 将轮廓绘制到形状图层中。
- 确保图层随视图调整大小:覆盖
layoutSubviews
视图,使其更新图层的框架并更新轮廓的路径。
- 您应该观察或覆盖
UIControl
的 state
属性(它是 UIButton
的祖先)以注意状态变化。
- 对形状图层的不透明度使用 属性 动画 (
CABasicAnimation
) 使轮廓淡入淡出。
序言(实际问题的代码后向下翻页):
我有一个自定义 UIButton
class,其中我用以下行为替换了普通的 UIButton
isHighlighted
动画行为:
当用户的手指实际放在按钮上时(即突出显示按钮),按钮周围会出现一个描边轮廓(方形边框)。当他们不再触摸按钮时,轮廓就会消失。
此外,我已将正常的 isSelected
行为(背景变为蓝色)替换为:
绘制了一个与isHighlighted
相同的轮廓,只是稍微粗一点,并且在isSelected = true
时一直存在,而在isSelected = false
时不存在。
这行得通,我就是这样做的:
import UIKit
class CustomButton: UIButton {
// BUTTON TYPES:
// Gorsh, enums sure would be swell here. :T
// 1 : plus
// 2 : minus
// 3 : etc etc....
@IBInspectable
var thisButtonsType: Int = 1 { didSet { setNeedsDisplay() } }
@IBInspectable
var fillColor: UIColor = .black { didSet { setNeedsDisplay() } }
@IBInspectable
var strokeColor: UIColor = .black { didSet { setNeedsDisplay() } }
override var isHighlighted: Bool {
didSet {
setNeedsDisplay()
}
}
override func draw(_ rect: CGRect) {
let unitOfMeasure = bounds.width / 5
// draw outline in case we are selected / highlighted
if (isSelected || isHighlighted) {
let tempPath = BezierPathFactory.outline(totalWidth: bounds.width)
if (isSelected) {tempPath.lineWidth = 4.0}
strokeColor.setStroke()
tempPath.stroke()
}
// initialize path object
var path = UIBezierPath()
// get the path corresponding to our button type
switch thisButtonsType {
case 1:
path = BezierPathFactory.plus(gridSpacing: unitOfMeasure)
case 2:
path = BezierPathFactory.minus(gridSpacing: unitOfMeasure)
default: print("hewo!")
}
fillColor.setFill()
path.fill()
}
}
再一次,该代码有效,但是...
我最想要的是,如果是高亮的边框轮廓会在触摸结束后逐渐消失。
注意:如果您想知道为什么我会这样做...我计划实现许多不同的按钮类型...它们上面都有不同的图标 "printed"...但是我希望他们都遵循这些基本行为。其中只有几个 "toggle" 按钮会被选中,因此高亮淡入淡出是有用的。
我已经知道如何制作动画...但我只是在绞尽脑汁思考如何在这种情况下制作动画。
我希望我能得到 UIButton 源代码。
有没有一种方法可以在不完全改变设计模式的情况下,相对简单地将淡入淡出动画添加到我的上述代码中?我是否必须开始使用核心图形的一些其他功能,如图层?
谢谢!
您可以执行以下操作:
- 创建
UIButton
的子层 class,它添加和管理 classCAShapeLayer
的子层,用于按钮的轮廓。 - 将轮廓绘制到形状图层中。
- 确保图层随视图调整大小:覆盖
layoutSubviews
视图,使其更新图层的框架并更新轮廓的路径。 - 您应该观察或覆盖
UIControl
的state
属性(它是UIButton
的祖先)以注意状态变化。 - 对形状图层的不透明度使用 属性 动画 (
CABasicAnimation
) 使轮廓淡入淡出。