简体   繁体   English

为什么 MagnificationGesture 在 SwiftUI 中只更新 state 一次?

[英]Why does MagnificationGesture only update the state once in SwiftUI?

I wish to have the following view respond to the magnification gestures, but it only works the first time.我希望下面的视图响应放大手势,但它只在第一次起作用。 The view can be magnified as expected, but after the view is released, subsequent touches do not trigger the gesture.视图可以按预期放大,但视图释放后,后续触摸不会触发手势。

Is there a way to have the gesture work continuously?有没有办法让手势连续工作?

struct Card: View {
    @State var magScale: CGFloat = 1

    var magnification: some Gesture {
        MagnificationGesture().onChanged { gesture in magScale = gesture }
    }

    var body: some View {
        Rectangle()
            .frame(width: 200, height: 200, alignment: .center)
            .scaleEffect(self.magScale)
            .gesture(magnification)
    }
}

The view is used like so:该视图的使用方式如下:

struct ContentView: View {
    var body: some View {
        ZStack {
            Color.blue
            Card()
        }
    }
}

Here is a solution.这是一个解决方案。 Tested with Xcode 12 (for below version some syntax might needed adapting)使用Xcode 12测试(对于以下版本,可能需要调整一些语法)

演示

struct Card: View {
    @State var magScale: CGFloat = 1
    @State var progressingScale: CGFloat = 1

    var magnification: some Gesture {
        MagnificationGesture()
            .onChanged { progressingScale = $0 }
            .onEnded {
                magScale *= $0
                progressingScale = 1
            }
    }

    var body: some View {
        Rectangle()
            .frame(width: 200, height: 200, alignment: .center)
            .scaleEffect(self.magScale * progressingScale)
            .gesture(magnification)
    }
}

Below code is working fine on the device.下面的代码在设备上运行良好。 No major change except adding the definition of tap and drag.除了添加点击和拖动的定义外,没有重大变化。

struct ContentView: View {
    var body: some View {

        ZStack {
            Color.blue
            Card()
        }
    }
}

struct Card: View {
    @State var magScale: CGFloat = 1
    @State var tapped: Bool = false
    @State var isDragging = false

    var magnification: some Gesture {
        MagnificationGesture().onChanged { gesture in
            self.magScale = gesture
        }
    }

    var tap: some Gesture {
        TapGesture(count: 1).onEnded { _ in
        self.tapped = !self.tapped
        }
    }

    var drag: some Gesture {
        DragGesture()
            .onChanged {_ in
                self.isDragging = true
            }
            .onEnded {_ in
                self.isDragging = false
            }
    }


    var body: some View {
        Rectangle()
            .foregroundColor(Color.green)
            .frame(width: 200, height: 200, alignment: .center)
            .scaleEffect(self.magScale)             
          .gesture(tap.simultaneously(with:magnification).simultaneously(with: drag))
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM