如何在自定义 UIButton 中实现 .isHighlighted 动画?

Posted

技术标签:

【中文标题】如何在自定义 UIButton 中实现 .isHighlighted 动画?【英文标题】:How to achieve .isHighlighted animation in a Custom UIButton? 【发布时间】:2018-10-04 05:26:49 【问题描述】:

序言(实际问题代码后向下翻页):

我有一个自定义的UIButton 类,在其中我用这种行为替换了普通的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()


    


再一次,该代码有效,但是...

我真正想要的是,如果 isHighlighted 边框轮廓在触摸完成后会逐渐消失。

注意:如果您想知道为什么我会这样做……我计划实现许多不同的按钮类型……所有按钮上都“打印”了不同的图标……但我想要它们全部遵循这些基本行为。其中只有几个是曾经被选中的“切换”按钮,因此可以使用高亮淡入淡出。

我已经知道如何制作动画......但我只是在想如何在这种情况下做到这一点。

我希望我能得到 UIButton 源代码。

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

谢谢!

【问题讨论】:

能否提供BezierPathFactory类的代码。顺便说一句,我认为使用图层会更容易。 我想我可以...不过它只是返回一个路径。 =T 【参考方案1】:

您可以执行以下操作:

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

【讨论】:

以上是关于如何在自定义 UIButton 中实现 .isHighlighted 动画?的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义相机中实现“捏放大”

如何在自定义 delphi 组件中实现 stringlist 属性?

如何使用edittexts在自定义ListView中实现监听器文本更改?

如何在自定义 OLE 对象中实现类似 Excel 的 OLE 链接行为

在自定义指令 angular 4 中实现 onclick()

如何在自定义文件浏览对话框Qt C++中实现返回和下一步按钮