围绕其中心旋转 UIImageView
Posted
技术标签:
【中文标题】围绕其中心旋转 UIImageView【英文标题】:Rotate UIImageView around its center 【发布时间】:2020-05-09 15:42:08 【问题描述】:我正在尝试将两个 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)
谢谢大家!
【问题讨论】:
您的图片资源似乎没有正确居中。设置图像视图的背景颜色,以便您知道。图像视图可能围绕其中心旋转,但图像内容本身可能偏离中心。 @PeterParker 我相信是这样,我更新了帖子并添加了带有背景的图像 gif。你知道如何让图片内容居中吗? 你必须在 Photoshop 中完成。 基本上你的戒指图片中间没有戒指。因此,您需要将该图像放入 Photoshop 并导出一个新图像,以使圆环位于中间。 @PeterParker 谢谢 【参考方案1】:为这个动画创建了一个圆形视图使用 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
Github Project Link
【讨论】:
谢谢@jawadAli 我会先尝试使用图片,因为我的客户可能会更改一些内容,但如果我将来需要,我已经下载了你的项目【参考方案2】:回答如下:
您的图片资源似乎没有正确居中。设置图像视图的背景颜色,以便您知道。图像视图可能围绕其中心旋转,但图像内容本身可能偏离中心。 - Peter Parker
基本上,您对戒指的印象中没有戒指在中间。因此,您需要将该图像放入 Photoshop 并导出一个新图像,以使圆环位于中间。 Peter Parker
谢谢Peter Parker
【讨论】:
以上是关于围绕其中心旋转 UIImageView的主要内容,如果未能解决你的问题,请参考以下文章