gpt4 book ai didi

ios - 在 Swift 4 中用一根手指进行旋转

转载 作者:可可西里 更新时间:2023-11-01 00:20:43 25 4
gpt4 key购买 nike

我创建了一个 UIGestureRecognizer 来仅用一根手指旋转 View 。

View 在开始时旋转,但一旦达到一定程度,旋转就会向另一个方向旋转。

你能帮我写代码吗?

UIViewcontroller <- 这里一切都很好

override func viewDidLoad() {
super.viewDidLoad()

// Do any additional setup after loading the view.

let wheel = TestWheelView()
wheel.frame = CGRect.init(x: self.view.center.x - 120, y: self.view.center.y - 120, width: 240, height: 240)
self.view.addSubview(wheel)
wheel.addGestureRecognizer(TestRotateGestureRecognizer())
}

UIGestureRecognizer <- 问题就在这里

import UIKit

class TestRotateGestureRecognizer: UIGestureRecognizer {
var previousPoint = CGPoint()
var currentPoint = CGPoint()
var startAngle = CGFloat()
var currentAngle = CGFloat()
var currentRotation = CGFloat()
var totalRotation = CGFloat()

func angleForPoint(_ point:CGPoint) -> CGFloat{
var angle = atan2(point.y - (self.view?.center.y)!, point.x - (self.view?.center.x)!)

return angle
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesBegan(touches, with: event)
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesMoved(touches, with: event)

if let firstTouch = touches.first {
previousPoint = firstTouch.previousLocation(in: self.view)
currentPoint = firstTouch.location(in: self.view)
startAngle = angleForPoint(previousPoint)
currentAngle = angleForPoint(currentPoint)

currentRotation = currentAngle - startAngle
totalRotation += currentRotation

self.view?.transform = CGAffineTransform(rotationAngle: totalRotation)
}
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesEnded(touches, with: event)
}
}

最佳答案

与其说是 Swift 问题,不如说是数学问题。关于数学部分,您需要检查计算旋转的方法的结果是否为负并返回绝对值,否则返回 360 减去角度:

 func angle(from location: CGPoint) -> CGFloat {
let deltaY = location.y - view.center.y
let deltaX = location.x - view.center.x
let angle = atan2(deltaY, deltaX) * 180 / .pi
return angle < 0 ? abs(angle) : 360 - angle
}

关于动画部分,我建议使用 CABasicAnimation,将 isRemovedOnCompletion 设置为 false,将 fillMode 设置为 kCAFillModeForwards,将 timingFunction 设置为 linear。另一个重要的设置是 from 和 to,你应该为它们使用相同的值,持续时间为 0:

fileprivate let rotateAnimation = CABasicAnimation()
func rotate(to: CGFloat, duration: Double = 0) {
rotateAnimation.fromValue = to
rotateAnimation.toValue = to
rotateAnimation.duration = duration
rotateAnimation.repeatCount = 0
rotateAnimation.isRemovedOnCompletion = false
rotateAnimation.fillMode = kCAFillModeForwards
rotateAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
imageView.layer.add(rotateAnimation, forKey: "transform.rotation.z")
}

要将度数转换为弧度,您可以使用此 answer 的扩展名:

extension FloatingPoint {
var degreesToRadians: Self { return self * .pi / 180 }
var radiansToDegrees: Self { return self * 180 / .pi }
}

要保持启动之间的旋转,您可以向 UserDefault 添加一个计算属性:

extension UserDefaults {
/// rotation persistant computed property
var rotation: CGFloat {
get {
return CGFloat(double(forKey: "rotation"))
}
set {
set(Double(newValue), forKey: "rotation")
}
}
}

关于手势识别器,您需要切换手势状态以检测它的开始、变化和结束并采取相应的行动:

fileprivate var rotation: CGFloat = UserDefaults.standard.rotation
fileprivate var startRotationAngle: CGFloat = 0
@objc func pan(_ gesture: UIPanGestureRecognizer) {
let location = gesture.location(in: view)
let gestureRotation = CGFloat(angle(from: location)) - startRotationAngle
switch gesture.state {
case .began:
// set the start angle of rotation
startRotationAngle = angle(from: location)
case .changed:
rotate(to: rotation - gestureRotation.degreesToRadians)
case .ended:
// update the amount of rotation
rotation -= gestureRotation.degreesToRadians
default :
break
}
// save the final position of the rotation to defaults
UserDefaults.standard.rotation = rotation
}

并将手势识别器添加到您的 View 中:

class ViewController: UIViewController, UIGestureRecognizerDelegate {
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
let address = "/image/xnZXF.jpg"
let url = URL(string: address)!
rotate(to: rotation)
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else { return }
DispatchQueue.main.async {
self.imageView.image = UIImage(data: data)
let pan = UIPanGestureRecognizer(target: self, action:#selector(self.pan))
pan.minimumNumberOfTouches = 1
pan.maximumNumberOfTouches = 1
pan.delegate = self
self.view.addGestureRecognizer(pan)
}
}.resume()
}
// rest of the view controller code
}

Sample project

关于ios - 在 Swift 4 中用一根手指进行旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48193915/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com