ios - Image scaling is disabled in SwiftUI - Stack Overflow

We have made it possible to scale, rotate, and move images using SwiftUI.The movement gesture is imple

We have made it possible to scale, rotate, and move images using SwiftUI. The movement gesture is implemented independently, while the zoom and rotation gestures can be performed simultaneously using SimultaneousGesture.

When repeatedly performing image zoom gestures, at some point the image seemed to freeze, and any further zoom, rotation, or movement gestures were no longer possible.

I would like to know the code that will solve this problem and make it possible to permanently scale images.

import SwiftUI

struct ContentView: View {

    @State private var offset: CGSize = .zero // drag value
    @State private var lastOffset: CGSize = .zero // hold last drag value
    @State private var scale: CGFloat = 1.0 // pinch scale value
    @State private var lastScale: CGFloat = 1.0 // hold last scale value
    @State private var angle: Angle = .zero // pinch angle value
    @State private var lastAngle: Angle = .zero // hold last angle value
    @State private var isReset: Bool = false

    let minScale = 0.2 // minimum scale value
    let maxScale = 5.0 // maximum scale value

    var dragGesture: some Gesture { // Move
        DragGesture()
            .onChanged {
                offset = CGSize(width: lastOffset.width + $0.translation.width, height: lastOffset.height + $0.translation.height)
            }
            .onEnded { _ in
                lastOffset = offset
            }
    }
    var scaleGesture: some Gesture { // Scaling
        MagnificationGesture()
            .onChanged {
                if ($0 > minScale) && ($0 < maxScale) { // scaling range for pinch
                    scale = $0 * lastScale
                }
            }
            .onEnded { _ in
                lastScale = scale
            }
    }
    var rotateGesture: some Gesture { // rotate
        RotationGesture(minimumAngleDelta: .degrees(8)) // minimun start angle = 8degrees
            .onChanged {
                angle = $0 + lastAngle
            }
            .onEnded { _ in
                lastAngle = angle
            }
    }

    var body: some View {
        NavigationStack {
        
            VStack {
                GeometryReader { geometry in
                
                    Image(systemName: "globe")
                        .resizable()
                        .scaledToFit()
                        .frame(maxWidth: .infinity, maxHeight: .infinity) // placement size
                        .rotationEffect(angle, anchor: .center) // rotationEffect must be first
                        .scaleEffect(scale) // scaleEffect must be after rotationEffect
                        .offset(offset) // offset is last
                        .gesture(dragGesture)
                        .gesture(SimultaneousGesture(rotateGesture, scaleGesture))
                }
                .toolbar {
                    ToolbarItem(placement: .topBarLeading) {
                        Spacer()
                    }
                    ToolbarItem(placement: .topBarTrailing) {
                        Button(action: {
                            isReset = true
                        }) {
                            Image(systemName: "arrow.trianglehead.clockwise")
                                .font(.title)
                                .foregroundColor(.red)
                        }
                    }
                }
            
            }
        }
        .onChange(of: isReset) {
            if (isReset == true) {
                offset = .zero; lastOffset = .zero
                scale = 1.0; lastScale = 1.0
                angle = .zero; lastAngle = .zero
            }
        
            isReset = false
        }
    }
}

We have made it possible to scale, rotate, and move images using SwiftUI. The movement gesture is implemented independently, while the zoom and rotation gestures can be performed simultaneously using SimultaneousGesture.

When repeatedly performing image zoom gestures, at some point the image seemed to freeze, and any further zoom, rotation, or movement gestures were no longer possible.

I would like to know the code that will solve this problem and make it possible to permanently scale images.

import SwiftUI

struct ContentView: View {

    @State private var offset: CGSize = .zero // drag value
    @State private var lastOffset: CGSize = .zero // hold last drag value
    @State private var scale: CGFloat = 1.0 // pinch scale value
    @State private var lastScale: CGFloat = 1.0 // hold last scale value
    @State private var angle: Angle = .zero // pinch angle value
    @State private var lastAngle: Angle = .zero // hold last angle value
    @State private var isReset: Bool = false

    let minScale = 0.2 // minimum scale value
    let maxScale = 5.0 // maximum scale value

    var dragGesture: some Gesture { // Move
        DragGesture()
            .onChanged {
                offset = CGSize(width: lastOffset.width + $0.translation.width, height: lastOffset.height + $0.translation.height)
            }
            .onEnded { _ in
                lastOffset = offset
            }
    }
    var scaleGesture: some Gesture { // Scaling
        MagnificationGesture()
            .onChanged {
                if ($0 > minScale) && ($0 < maxScale) { // scaling range for pinch
                    scale = $0 * lastScale
                }
            }
            .onEnded { _ in
                lastScale = scale
            }
    }
    var rotateGesture: some Gesture { // rotate
        RotationGesture(minimumAngleDelta: .degrees(8)) // minimun start angle = 8degrees
            .onChanged {
                angle = $0 + lastAngle
            }
            .onEnded { _ in
                lastAngle = angle
            }
    }

    var body: some View {
        NavigationStack {
        
            VStack {
                GeometryReader { geometry in
                
                    Image(systemName: "globe")
                        .resizable()
                        .scaledToFit()
                        .frame(maxWidth: .infinity, maxHeight: .infinity) // placement size
                        .rotationEffect(angle, anchor: .center) // rotationEffect must be first
                        .scaleEffect(scale) // scaleEffect must be after rotationEffect
                        .offset(offset) // offset is last
                        .gesture(dragGesture)
                        .gesture(SimultaneousGesture(rotateGesture, scaleGesture))
                }
                .toolbar {
                    ToolbarItem(placement: .topBarLeading) {
                        Spacer()
                    }
                    ToolbarItem(placement: .topBarTrailing) {
                        Button(action: {
                            isReset = true
                        }) {
                            Image(systemName: "arrow.trianglehead.clockwise")
                                .font(.title)
                                .foregroundColor(.red)
                        }
                    }
                }
            
            }
        }
        .onChange(of: isReset) {
            if (isReset == true) {
                offset = .zero; lastOffset = .zero
                scale = 1.0; lastScale = 1.0
                angle = .zero; lastAngle = .zero
            }
        
            isReset = false
        }
    }
}
Share Improve this question asked Mar 27 at 13:50 BB-8BB-8 1075 bronze badges 3
  • You will be able to instantly find a problem if you simply add some print statements inside the changed and on ended clauses. I can't really figure out all your code, but I'm guessing you almost certainly need to do something as well when the gesture begins as well as change and end, and don't fet cancel as well. As I say, if you just add print statements, you'll instantly find the problem. Writing touch related code is very subtle and tricky. – Fattie Commented Mar 27 at 17:51
  • I checked the situation using the print statement, but couldn't determine the cause, so I submitted Feedback to Apple. FB17031685 – BB-8 Commented Mar 28 at 5:59
  • Since MagnificationGesture is already deprecated, I checked using MagnifyGesture but I am getting the same issue. – BB-8 Commented Mar 28 at 6:00
Add a comment  | 

1 Answer 1

Reset to default -1

This issue does not occur if you define the image scaling gesture alone.

Problems arise when SimultaneousGesture allows multiple gestures to be performed simultaneously.

.gesture(scaleGesture)  --->  No problems occur

.gesture(SimultaneousGesture(rotateGesture, scaleGesture))  ----> Problems occur

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744084342a4555886.html

相关推荐

  • ios - Image scaling is disabled in SwiftUI - Stack Overflow

    We have made it possible to scale, rotate, and move images using SwiftUI.The movement gesture is imple

    9天前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信