【问题标题】:How to launch gradient animation on button tapped?如何在点击按钮时启动渐变动画?
【发布时间】:2019-12-31 16:15:38
【问题描述】:

我正在创建一个 IOS 应用程序。我有 5 个使用 UIBezierPath 创建的星形按钮。当我点击特定的星星时,我想填充它们。例如。如果我点击第三颗星,那么渐变将填充 3 颗第一颗星等。

我已经创建了 5 星的视图。在绘制视图方法中,我添加了用于动画渐变的代码,它仅在视图启动时才能正常工作。

 override func draw(_ rect: CGRect) {

        let path = UIBezierPath()
        UIColor.black.setStroke()
        path.lineWidth = 2
        let numberOfPoints = 5
        var angle: CGFloat = CGFloat.pi / 2
        let angleOfIncrement = CGFloat.pi*2/CGFloat(numberOfPoints)
        let radius: CGFloat = rect.origin.x + rect.width/2
        let offset = CGPoint(x: rect.origin.x + rect.width/2, y: rect.origin.y + rect.height/2)
        let midleRadius = radius*0.45
        var firstStar = true


        for _ in 1...numberOfPoints {
            let firstPoint = getPointLocation(angle: angle, radius: midleRadius, offset: offset)
            let midlePoint = getPointLocation(angle: angle+angleOfIncrement/2, radius: radius, offset: offset)
            let secondPoint = getPointLocation(angle: angle+angleOfIncrement, radius: midleRadius, offset: offset)

            if firstStar {
                firstStar = false
                path.move(to: firstPoint)
                path.addLine(to: midlePoint)
                path.addLine(to: secondPoint)
            }else {
                path.addLine(to: firstPoint)
                path.addLine(to: midlePoint)
                path.addLine(to: secondPoint)
            }

            angle += angleOfIncrement

        }
        path.stroke()

            let shapeLayer = CAShapeLayer()
            shapeLayer.path = path.cgPath
            let gradient = CAGradientLayer(layer: layer)
            gradient.colors = [UIColor.black.cgColor, UIColor.white.cgColor]
            gradient.locations = [1]
            gradient.startPoint = CGPoint(x: 0, y: 1)
            gradient.endPoint = CGPoint(x: 1, y: 1)
            gradient.frame = path.bounds

            self.layer.addSublayer(gradient)

            let animation = CABasicAnimation(keyPath: "locations")
            animation.fromValue = [0, 0]
            animation.toValue = [0, 1.0]
            animation.duration = 3
            gradient.add(animation, forKey: nil)

            self.layer.mask = shapeLayer


    }

我希望当我点击第 3 颗星时,渐变会填充前 3 颗星。

【问题讨论】:

  • 选星后调用draw有用吗?
  • 是的,但是我在点击星号后动画有问题。

标签: swift uibezierpath cashapelayer cabasicanimation cagradientlayer


【解决方案1】:

您必须将绘图代码与动画代码分开,并且(顺便说一句)您还应该(重新)将图层创建移出draw()

对于分离动作

let animation = CABasicAnimation(keyPath: "locations")
animation.fromValue = [0, 0]
animation.toValue = [0, 1.0]
animation.duration = 3
gradient.add(animation, forKey: nil)

到一个单独的方法中,并在需要时调用它。

您还必须从draw()中删除层创建,因为如果需要(重新)绘制视图,则始终调用此方法。这会产生严重的内存泄漏,因为例如 iPhone 的每次旋转都会创建一个新的渐变层。

您的代码中还有另一个问题。您的渐变层位于视图层之上。那是行不通的。您可以将渐变层添加到视图层,并使用蒙版将星星从渐变中剪掉。

【讨论】:

  • 也许我不够清楚...有一个视频描述了这种情况youtu.be/1XpBn45PWSg。我想要渐变填充星星。例如。如果我点击第三颗星,那么渐变将填充 3 颗第一颗星等。
猜你喜欢
  • 1970-01-01
  • 2011-09-08
  • 2020-03-02
  • 2017-05-18
  • 1970-01-01
  • 2011-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多