如何仅用一根手指在 SwiftUI 中旋转图像?

How can i rotate an image in SwiftUI with one finger only?

我在视图中有一张图片,我想只用一根手指旋转它,我如何在 SwiftUI 中做到这一点?

我检查了 RotationGesture,但它只适用于两个手指...

谢谢

一指旋转

struct RotationGesture: View {
        @State var gestureValue = CGSize.zero
        var body: some View {
            Text("Hello, World!")
                .frame(width: 150, height: 60)
                .padding()
                .background(Color.orange)
                .cornerRadius(15)
                .rotationEffect(Angle(degrees: Double(-gestureValue.width)))
                .gesture(
                    DragGesture().onChanged({ (value) in
                        self.gestureValue = value.translation
                    }).onEnded({ (value) in
                        self.gestureValue = .zero
                    })
                )
                .animation(.spring(response: 0.5, dampingFraction: 0.6, blendDuration: 0))
        }
    }

好的,用这段代码修复它:

struct RotationGesture: View {
    @State var totalRotation = CGSize.zero
    @State var currentRotation = CGSize.zero
    
    var body: some View {
        Text("Hello, World!")
            .frame(width: 150, height: 60)
            .padding()
            .background(Color.orange)
            .cornerRadius(15)
            .rotationEffect(Angle(degrees: Double(-totalRotation.width)))
            .gesture(
                DragGesture()
                    .onChanged { value in
                        totalRotation.width = value.translation.width + currentRotation.width
                    }
                    .onEnded { value in
                        currentRotation = totalRotation
                    }
            )
    }
}

但现在我们必须修复垂直移动,因为此解决方案仅在绕 X 轴移动时有效...

当您围绕要旋转的视图进行圆周运动时,我想解决这个问题...

好的,我用这段代码搞定了:
https://gist.github.com/ts95/9f8e05380824c6ca999ab3bc1ff8541f

A dragGesture 将为我们提供用户在屏幕上拖动的位置的值(在我们的例子中为圆圈)。在这里,圆框将等高和等宽。

捕获用户点击的位置点并从 y 点减去 height/2 并从 x 点减去 width/2 结果 deltaXdeltaY。一旦我们有了 deltaXdeltaY,我们就可以使用 atan2 函数(由 Swift 标准库提供)将其转换为弧度。

struct SwiftUIView: View {
    
    @State var angle: Angle = .zero
    var circleFrame: CGRect = CGRect(x: 0, y: 0, width: 300, height: 300)

    var body: some View {
        Circle()
            .fill(AngularGradient(gradient: Gradient(colors: [Color.red, Color.blue]), center: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/, angle: .degrees(90)))
            .padding()
            .rotationEffect(angle)
            .gesture(
                DragGesture()
                    .onChanged { value in
                        let deltaY = value.location.y - (circleFrame.height / 2)
                        let deltaX = value.location.x - (circleFrame.width / 2)
                        angle = Angle(radians: Double(atan2(deltaY, deltaX)))  
                    }
            )
    }
}