SwiftUI DragGestures 在触发不同的 DragGesture 之前不会更新

SwiftUI DragGestures not updating until different DragGesture triggered

这张 gif 应该很清楚地显示了我的问题。

换句话说,我有一个用于背景颜色的 DragGesture 和一个用于添加 Text() 视图的 TapGesture。每个 Text View 上都有一个 DragGesture 以在拖动时更新其位置。 这有效,但 视觉上 文本视图位置不会更新,直到我激活背景色 DragGesture。我已确认 Text Views 位置值已更新,只是视觉上没有更新。

此外,我有一个长按手势,通过阻止调用 moodColor() 来 'locks' 背景颜色。当它被锁定时,文本视图将不会移动,直到我再次长按解锁它,然后然后拖动背景颜色。

我觉得我在滥用 DragGestures,但显然每个视图都应该有自己的手势。

这是代码。

class Note : Identifiable{
    var id = UUID()
    var text: Text
    var dragOffset : CGPoint
     @GestureState private var location: CGPoint = .zero
    var drag : some Gesture{ DragGesture(minimumDistance: 0.5, coordinateSpace: .global).onChanged{ value in self.dragOffset = value.location }
        .updating($location){ (value, state, transaction) in state = value.location }
    }

    init(textVal: String){
        self.text = Text(textVal).font(.largeTitle)
        self.dragOffset = CGPoint(x: 50, y: 50)
    }
}

struct Col{
    var red: Double = 1.0
    var green: Double = 1.0
    var blue: Double = 1.0
}

struct ContentView: View {
    @State var brightness = 0.9
    @State var color = Col()        // Color Grid Style, RGB
    @GestureState var dragInfo = CGSize.zero
    @State private var myviews: [Note] = []
    @State private var colorLocked = false

    var body: some View {
        return GeometryReader { geo in
            Color.init( red: self.color.red * self.brightness, green: self.color.green * self.brightness, blue: self.color.blue * self.brightness)

                .edgesIgnoringSafeArea(.all)
                .gesture( TapGesture().onEnded{ value in self.myviews.append(Note(textVal: "A Note")) })
                .gesture( LongPressGesture(minimumDuration: 0.5).onEnded{
                            _ in UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
                            self.colorLocked = !self.colorLocked })
                .gesture( DragGesture().onChanged{
                            if !self.colorLocked { self.moodColor(data: [=10=], width: geo.size.width, height: geo.size.height) }}) 
                                                  // moodColor() does math to change the background
                .gesture( MagnificationGesture().onChanged{
                            self.brightness = Double([=10=].magnitude + 0.5)
                })

            ForEach(self.myviews) { note in
                note.text.gesture(note.drag).position(note.dragOffset) }}
    }

保持你的 Views Views 不在模型 class

import SwiftUI
class Note : Identifiable{
    var id = UUID()
    var dragOffset : CGSize
    var textVal: String
    init(textVal: String){
        self.textVal = textVal
        self.dragOffset = .zero
    }
}

struct Col{
    var red: Double = 1.0
    var green: Double = 1.0
    var blue: Double = 1.0
}
struct AnimatedText: View {
    var note: Note
    @GestureState private var location: CGPoint = .zero
    @State private var offset: CGSize = .zero
    var drag : some Gesture{ DragGesture()
        .onChanged {
            self.offset.height = self.note.dragOffset.height + [=10=].translation.height
            self.offset.width = self.note.dragOffset.width + [=10=].translation.width
    }
    .onEnded { _ in
        self.note.dragOffset = self.offset//self.offset = .zero
        }
    }

    var body: some View {
        Text(note.textVal)
            .font(.largeTitle)
            .offset(x: offset.width, y: offset.height)
            .gesture(drag)
    }
}
struct DragGestureNotMoving: View {
    @State var brightness = 0.9
    @State var color = Col()        // Color Grid Style, RGB
    @GestureState var dragInfo = CGSize.zero
    @State private var myNotes: [Note] = []
    @State private var colorLocked = false
    var body: some View {
        return GeometryReader { geo in
            Color.init( red: self.color.red * self.brightness, green: self.color.green * self.brightness, blue: self.color.blue * self.brightness)

                .edgesIgnoringSafeArea(.all)
                .gesture( TapGesture().onEnded{ value in self.myNotes.append(Note(textVal: "A Note")) })
                .gesture( LongPressGesture(minimumDuration: 0.5).onEnded{
                    _ in UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
                    self.colorLocked = !self.colorLocked })
                //.gesture( DragGesture().onChanged{_ in if !self.colorLocked {self.moodColor(data: [=10=], width: geo.size.width, height: geo.size.height) }})// moodColor() does math to change the background
                .gesture( MagnificationGesture().onChanged{
                    self.brightness = Double([=10=].magnitude + 0.5)
                })

            ForEach(self.myNotes) { note in
                AnimatedText(note: note)

            }

        }
    }
}

我评论了 moodColor(),因为我没有额外的代码,但移动与更改一起工作。如果您有其他问题,请查看 SimultaneosGesture。

https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/coordinating_multiple_gesture_recognizers/allowing_the_simultaneous_recognition_of_multiple_gestures