围绕其中心旋转 UIImageView
Rotate UIImageView around its center
我正在尝试旋转两个 UIImage 的中心,但我遇到了问题(您可以查看下面的 gif 图片),旋转没问题,但图像上下摆动,有人知道这是什么吗可以吗?
Loader Animation
Loader Animation with background color
这是我用来旋转图像的代码
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)
}
}
谢谢大家!
回答如下:
It looks like your image asset isn’t centred properly. Set the background colour of your image view so you can tell. The image view is probably rotating about its center, but the image content itself is probably off center. - Peter Parker
Basically your image of the rings does not have the rings smack in the middle. So you need to put that image into photoshop and export a new one such that the rings are smack in the middle.
Peter Parker
为此动画创建了一个圆形视图使用 ShapeLayer 和 UIBezierPath 你可以使用这个 class
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
}
}
我正在尝试旋转两个 UIImage 的中心,但我遇到了问题(您可以查看下面的 gif 图片),旋转没问题,但图像上下摆动,有人知道这是什么吗可以吗?
Loader Animation
Loader Animation with background color
这是我用来旋转图像的代码
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)
}
}
谢谢大家!
回答如下:
It looks like your image asset isn’t centred properly. Set the background colour of your image view so you can tell. The image view is probably rotating about its center, but the image content itself is probably off center. - Peter Parker
Basically your image of the rings does not have the rings smack in the middle. So you need to put that image into photoshop and export a new one such that the rings are smack in the middle. Peter Parker
为此动画创建了一个圆形视图使用 ShapeLayer 和 UIBezierPath 你可以使用这个 class
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
}
}