【问题标题】:SwiftUI DragGestures not updating until different DragGesture triggered在触发不同的 DragGesture 之前,SwiftUI DragGestures 不会更新
【发布时间】:2020-02-08 21:19:01
【问题描述】:

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

换句话说,我有一个 DragGesture 用于背景颜色,而 TapGesture 用于添加 Text() 视图。每个文本视图上都有一个 DragGesture 以在拖动时更新其位置。 这可行,但在我激活背景颜色 DragGesture 之前,视觉上文本视图位置不会更新。我已经确认文本视图位置值会更新,它们只是不会在视觉上更新。

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

我有一种误用 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: $0, width: geo.size.width, height: geo.size.height) }}) 
                                                  // moodColor() does math to change the background
                .gesture( MagnificationGesture().onChanged{
                            self.brightness = Double($0.magnitude + 0.5)
                })

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

【问题讨论】:

    标签: ios swift swiftui draggesture


    【解决方案1】:

    保持您的ViewsViews 不在模型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 + $0.translation.height
                self.offset.width = self.note.dragOffset.width + $0.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: $0, width: geo.size.width, height: geo.size.height) }})// moodColor() does math to change the background
                    .gesture( MagnificationGesture().onChanged{
                        self.brightness = Double($0.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

    【讨论】:

    • 哦,我明白了。所以本质上我需要定义一个自定义视图,并使用它来存储和显示 Note 类。然后将手势附加到新的自定义视图上。
    猜你喜欢
    • 2021-06-05
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-03
    相关资源
    最近更新 更多