如何在自定义 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 源代码。

有没有一种方法可以在不完全改变设计模式的情况下,相对简单地将淡入淡出动画添加到我的上述代码中?我是否必须开始使用核心图形的一些其他功能,如图层?

谢谢!

您可以执行以下操作:

  1. 创建 UIButton 的子层 class,它添加和管理 class CAShapeLayer 的子层,用于按钮的轮廓。
  2. 将轮廓绘制到形状图层中。
  3. 确保图层随视图调整大小:覆盖 layoutSubviews 视图,使其更新图层的框架并更新轮廓的路径。
  4. 您应该观察或覆盖 UIControlstate 属性(它是 UIButton 的祖先)以注意状态变化。
  5. 对形状图层的不透明度使用 属性 动画 (CABasicAnimation) 使轮廓淡入淡出。