Ios 围绕其中心旋转UIImageView

Ios 围绕其中心旋转UIImageView,ios,swift,rotation,uiimageview,uibezierpath,Ios,Swift,Rotation,Uiimageview,Uibezierpath,我正试图将两个UIImage旋转到它的中心,我遇到了一个问题(你可以查看下面的gif图像),旋转很好,但是图像上下浮动,有人知道它是什么吗 下面是我用来旋转图像的代码 extension UIView { private static let kRotationAnimationKey = "rotationAnimationKey" func rotate(_ reversed: Bool = false, _ duration: Double = 1) { if layer.

我正试图将两个UIImage旋转到它的中心,我遇到了一个问题(你可以查看下面的gif图像),旋转很好,但是图像上下浮动,有人知道它是什么吗

下面是我用来旋转图像的代码

extension UIView {

private static let kRotationAnimationKey = "rotationAnimationKey"

func rotate(_ reversed: Bool = false, _ duration: Double = 1) {
    if layer.animation(forKey: UIView.kRotationAnimationKey) == nil {
        let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation")
        rotationAnimation.fromValue = 0.0
        rotationAnimation.toValue = reversed ? -(Float.pi * 2.0) : Float.pi * 2.0
        rotationAnimation.duration = duration
        rotationAnimation.repeatCount = Float.infinity
        layer.add(rotationAnimation, forKey: UIView.kRotationAnimationKey)
    }
}

func stopRotating() {
    if layer.animation(forKey: UIView.kRotationAnimationKey) != nil {
        layer.removeAnimation(forKey: UIView.kRotationAnimationKey)
    }
}
谢谢大家!

回答如下:


看起来您的图像资源没有正确居中。设置图像视图的背景色,以便您可以辨别。图像视图可能围绕其中心旋转,但图像内容本身可能偏离中心。-


基本上你的戒指的形象没有中间的戒指。所以你需要把这个图像放到PS图象处理软件里,然后输出一个新的,这样戒指就在中间。


谢谢

使用ShapeLayer和UIBezierPath为该动画创建了一个圆形视图。您可以使用该类

public class CirclesView: UIView {

    //MARK:- properties
    private var numberOfCircles: Int = 2
    private var lineWidth: CGFloat = 8.0
    private var space = 20
    private var color : UIColor = .white
    private static let kRotationAnimationKey = "rotationanimationkey"

    private lazy var circularLayer: CAShapeLayer = {
        let shapeLayer = CAShapeLayer()
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.strokeColor = color.cgColor
        shapeLayer.lineCap = .round
        shapeLayer.lineWidth = self.lineWidth

        return shapeLayer
    }()

    //MARK:- inializer

    public init(_ circles: Int, circleWidth: CGFloat) {
        self.numberOfCircles = circles
        self.lineWidth = circleWidth
        super.init(frame: .zero)
        addSubLayer()
    }

    override init(frame: CGRect) {

        super.init(frame: frame)
        addSubLayer()
    }

    required init?(coder: NSCoder) {

        super.init(coder: coder)
        addSubLayer()
    }

    override public func layoutSubviews() {

        super.layoutSubviews()
        addCircles()

    }


}
private extension CirclesView {

    func addCircles() {
        circularLayer.bounds = self.bounds
        let bezierPath = UIBezierPath()

        let center = CGPoint(x: bounds.maxX / 2, y: bounds.maxY / 2)
        let maximumRadius =  min(bounds.maxX,bounds.maxY)/2 - (lineWidth / 2.0)
        var startAngle = CGFloat(60)
        var endAngle = CGFloat(130)


        for i in 1...numberOfCircles {

            let radius = maximumRadius - CGFloat(i * space)
            let  startX = center.x  + (radius) * CGFloat(cos(startAngle.deg2rad()))
            let  startY = center.y  + (radius) * CGFloat(sin(startAngle.deg2rad()))

            bezierPath.move(to: CGPoint(x: startX,y: startY))
            bezierPath.addArc(withCenter: center, radius: radius, startAngle: startAngle.deg2rad(), endAngle: endAngle.deg2rad(), clockwise: false)

            startAngle = startAngle - 10
            endAngle = endAngle + 50

        }

        circularLayer.path = bezierPath.cgPath
    }

    func addSubLayer() {
        self.backgroundColor = .clear
        layer.addSublayer(circularLayer)

    }


}

 //MARK:- Public Functions
public extension CirclesView {

    func startAnimation(_ reversed: Bool = false, _ duration: Double = 1) {

        let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
        rotateAnimation.fromValue = 0.0
        rotateAnimation.toValue = reversed ? -(Float.pi * 2.0) : Float.pi * 2.0
        rotateAnimation.duration = duration
        rotateAnimation.repeatCount = Float.infinity
        self.circularLayer.add(rotateAnimation, forKey: Self.kRotationAnimationKey)
    }

    func stopAnimation() {
        if let _ = circularLayer.animation(forKey: Self.kRotationAnimationKey)  {

            let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
            rotateAnimation.fromValue = circularLayer.presentation()?.value(forKeyPath: "transform.rotation")
            rotateAnimation.toValue = 0
            rotateAnimation.duration = 0.5
            rotateAnimation.repeatCount = 0
            rotateAnimation.isRemovedOnCompletion = true
            self.circularLayer.removeAnimation(forKey: Self.kRotationAnimationKey)
            self.circularLayer.add(rotateAnimation, forKey: Self.kRotationAnimationKey)
        }
    }

    func pauseLayer(){
        let pausedTime : CFTimeInterval = layer.convertTime(CACurrentMediaTime(), from: nil)
        circularLayer.speed = 0.0
        circularLayer.timeOffset = pausedTime
    }
}


 extension CGFloat {
    func deg2rad() -> CGFloat {
        return self * .pi / 180
    }
}


看起来您的图像资源没有正确居中。设置图像视图的背景色,以便您可以辨别。图像视图可能围绕其中心旋转,但图像内容本身可能偏离中心。@PeterParker我想是的,我更新了文章并添加了带有背景的gif图像。你知道如何处理图像内容吗?你必须在PS图象处理软件上做。基本上你的戒指的图像没有中间的戒指。所以你需要把这个图像放到PS图象处理软件中,然后导出一个新的环,这样戒指就在中间。@ Paer-PARKER谢谢你。JavaDali我会先试用图像,因为我的客户可能会改变一些东西,但是我已经下载了你的项目,如果我需要它的话。