SwiftUI DragGestures не обновляется, пока не будет запущен другой DragGesture - PullRequest
1 голос
/ 09 февраля 2020

этот gif должен довольно четко показать мою проблему.

enter image description here

На словах у меня есть DragGesture для цвета фона и TapGesture для добавления текста () взгляды. Каждый текстовый вид имеет 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) }}
    }

1 Ответ

0 голосов
/ 09 февраля 2020

Оставьте 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 + $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(), поскольку у меня нет дополнительного кода, но движение работает с изменениями. Если у вас возникли другие проблемы, загляните в SimweenosGesture.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...