【问题标题】:How to create an animation that rotate CAShapeLayer in swift如何创建快速旋转 CAShapeLayer 的动画
【发布时间】:2016-03-12 06:56:45
【问题描述】:

这是我的代码: 导入 UIKit

class circularLoaderView: UIView {

    let circlePathLayer = CAShapeLayer()
    let circleRadius: CGFloat = 20.0



    override init(frame: CGRect) {

        super.init(frame: frame)
        configure()

    }

    required init(coder aDecoder: NSCoder) {

        super.init(coder: aDecoder)!
        configure()
    }

    func configure() {


        circlePathLayer.frame = bounds
        circlePathLayer.lineWidth = 2
        circlePathLayer.fillColor = UIColor.clearColor().CGColor
        circlePathLayer.strokeColor = UIColor.redColor().CGColor

        layer.addSublayer(circlePathLayer)
        backgroundColor = UIColor.whiteColor()



    }

    func circleFrame() -> CGRect {
        var circleFrame = CGRect(x: 0, y: 0, width: 2*circleRadius, height: 2*circleRadius)
        circleFrame.origin.x = 20
        circleFrame.origin.y = 20


        return circleFrame
    }




     func circlePath() -> UIBezierPath {


        let startAngle = CGFloat(-M_PI_2)
        let endAngle = startAngle + CGFloat(M_PI * 2)



        return UIBezierPath(arcCenter: CGPoint(x: circleRadius, y: circleRadius), radius: circleRadius, startAngle: startAngle, endAngle: endAngle, clockwise: true)


     }



    override func layoutSubviews() {
        super.layoutSubviews()

        circlePathLayer.frame = bounds
        circlePathLayer.path = circlePath().CGPath
        circlePathLayer.strokeEnd = 0.25


        circlePathLayer.addAnimation(rotationAnimation, forKey: "transform.rotation")


    }


    let rotationAnimation: CAAnimation = {
        let animation = CABasicAnimation(keyPath: "transform.rotation")
        animation.fromValue = 0
        animation.toValue = M_PI * 2
        animation.duration = 4


        animation.repeatCount = MAXFLOAT
        return animation
    }()


}

这是我的代码,我创建了一个 CAShapeLayer,它将旋转并因此产生加载器效果,但是当我添加 rotationAnimation 的动画时,它会围绕一个中心点旋转整个 CAShapeLayer,而不是 CAShapeLayer 本身。为什么会这样?我该如何解决?谢谢

【问题讨论】:

    标签: ios swift cashapelayer


    【解决方案1】:

    你应该像这样设置锚点:

    layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    

    【讨论】:

      【解决方案2】:

      您的案例应该非常适合 size(width: 40, height: 40) 的视图。

      如果您想概括让您的 circularLoaderView 也适用于其他尺寸,您需要

      1. 将半径指定为视图高度或宽度的一半(因为高度=宽度)。

        var circleRadius: CGFloat {
        
          return bounds.size.height/2
        
         }
        
      2. 同样,您的中心也应位于视图的中心,即

        circleFrame.origin.x = bounds.size.height/2
        circleFrame.origin.y = bounds.size.height/2
        

      以下是在 Swift 3

      中可以正常工作的修改后的代码
      class circularLoaderView: UIView {
      
          let circlePathLayer = CAShapeLayer()
          var circleRadius: CGFloat {
              return bounds.height/2
          }
      
          override init(frame: CGRect) {
              super.init(frame: frame)
              configure()
      
          }
      
          required init(coder aDecoder: NSCoder) {
              super.init(coder: aDecoder)!
              configure()
          }
      
          func configure() {
              circlePathLayer.frame = bounds
              circlePathLayer.lineWidth = 2
              circlePathLayer.fillColor = UIColor.clear.cgColor
              circlePathLayer.strokeColor = UIColor.red.cgColor
      
              layer.addSublayer(circlePathLayer)
              backgroundColor = UIColor.white
          }
      
          //This method is not being used
          /*func circleFrame() -> CGRect {
              var circleFrame = CGRect(x: circleRadius , y: circleRadius, width: 2*circleRadius, height: 2*circleRadius)
              circleFrame.origin.x = circleRadius
              circleFrame.origin.y = circleRadius
      
              return circleFrame
          }*/
      
          func circlePath() -> UIBezierPath {
              let startAngle = CGFloat(-Double.pi/2)
              let endAngle = startAngle + CGFloat(Double.pi * 2)
      
              return UIBezierPath(arcCenter: CGPoint(x: circleRadius, y: circleRadius), radius: circleRadius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
          }
      
          override func layoutSubviews() {
              super.layoutSubviews()
      
              circlePathLayer.frame = bounds
              circlePathLayer.path = circlePath().cgPath
              circlePathLayer.strokeEnd = 0.25
              circlePathLayer.add(rotationAnimation, forKey: "transform.rotation")
      
          }
      
          let rotationAnimation: CAAnimation = {
              let animation = CABasicAnimation(keyPath: "transform.rotation")
              animation.fromValue = 0
              animation.toValue = Double.pi * 2
              animation.duration = 4    
              animation.repeatCount = MAXFLOAT
      
              return animation
          }()
      }
      

      我知道这个问题很久以前就发布了,但我只是希望这能解决正在寻找类似问题的人的问题。

      【讨论】:

        猜你喜欢
        • 2015-10-07
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多