在 iOS 中围绕枢轴点旋转 ImageView

2024-03-21

记录和旋转搜索栏

我在下面有一个应用程序屏幕来录制(最多 30 秒)音频。

  1. 如何在录制音频时平滑地将小圆圈旋转为虚线圆线上的搜索栏?
  2. 当小圆圈沿线旋转时,如何填充虚线。

Thanks.


答案是有两种方法可以使用PanGesture并自动使用Timer.

1.使用UIPanGestureRecognizer:

您可以使用以下方法实现此目的UIPanGestureRecognizer. circleView是你的mainView and nob是另一个view or imageView它将移出circleView

panGesture = UIPanGestureRecognizer(target: self, action: #selector(panHandler(_:)))
nob.addGestureRecognizer(panGesture)

的定义panHandler(_ :)

@objc func panHandler(_ gesture: UIPanGestureRecognizer) {
    let point = gesture.location(in: self)
    updateForPoints(point)
}

这是它如何工作的核心逻辑。

func updateForPoints(_ point: CGPoint) {

    /*
     * Parametric equation of circle
     * x = a + r cos t
     * y = b + r sin ⁡t
     * a, b are center of circle
     * t (theta) is angle
     * x and y will be points which are on circumference of circle
     *
               270
                |
            _   |   _
                |
     180 -------o------- 360
                |
            +   |   +
                |
               90
     *
     */

    let centerOffset =  CGPoint(x: point.x - circleView.frame.midX, y: point.y - circleView.frame.midY)

    let a: CGFloat = circleView.center.x
    let b: CGFloat = circleView.center.y
    let r: CGFloat = circleView.layer.cornerRadius - 2.5
    let theta: CGFloat = atan2(centerOffset.y, centerOffset.x)
    let newPoints = CGPoint(x: a + r * cos(theta), y: b + r * sin(theta))

    var rect = nob.frame
    rect.origin = newPoints
    nob.center = newPoints
}

2. 使用定时器自动移动

let totalSeconds: Int = 30 // You can change it whatever you want
var currentSecond: Int = 1
var timer: Timer?


func degreesToRadians(_ degree: CGFloat) -> CGFloat {
     /// Will convert the degree (180°) to radians (3.14)
     return degree * .pi / 180
}

func angleFromSeconds(_ seconds: Int) -> CGFloat {
     /// Will calculate the angle for given seconds
     let aSliceAngle = 360.0 / CGFloat(totalSeconds)
     let angle = aSliceAngle * CGFloat(seconds) - 90
     return angle
}

/// ------------- TIMER METHODS ------------- ///

func startTimer() {
     stopTimer()
     timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(timeDidUpdate(_ :)), userInfo: nil, repeats: true)
     timeDidUpdate(timer!)
}

func stopTimer() {
     currentSecond = 1
     timer?.invalidate()
     timer = nil
}

@objc func timeDidUpdate(_ t: Timer) {
      let angle = angleFromSeconds(currentSecond)
      let theta = degreesToRadians(angle)
      updateAngle(theta: theta, animated: true)
      currentSecond += 1

      if currentSecond > totalSeconds {
         self.stopTimer()
      }
}

/// --------------- MAIN METHOD -------------- ///
func updateAngle(theta: CGFloat, animated: Bool) {

     let a: CGFloat = circleView.center.x
     let b: CGFloat = circleView.center.y
     let r: CGFloat = circleView.layer.cornerRadius
     let newPoints = CGPoint(x: a + r * cos(theta), y: b + r * sin(theta))

     var rect = nob.frame
     rect.origin = newPoints

     if animated {
         UIView.animate(withDuration: 0.1, animations: {
         self.nob.center = newPoints

         /// Uncomment if your nob is not a circle and you want to maintain the angle too
         // self.nob.transform = CGAffineTransform.identity.rotated(by: theta)
         })
     }
     else {
         nob.center = newPoints

         /// Uncomment if your nob is not a circle and you want to maintain the angle too
         //nob.transform = CGAffineTransform.identity.rotated(by: theta)
     }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 iOS 中围绕枢轴点旋转 ImageView 的相关文章

随机推荐