SwiftUI DragGestures не обновляется до тех пор, пока не будет запущен другой DragGesture
Эта гифка должна довольно ясно показать мою проблему.
Проще говоря, у меня есть DragGesture для цвета фона и TapGesture для добавления представлений Text(). Каждое текстовое представление имеет DragGesture для обновления его местоположения при перетаскивании. Это работает, но визуально положение текстовых представлений не обновляется, пока я не активирую цвет фона DragGesture. Я подтвердил, что значения позиции Text Views обновляются, они просто не обновляются визуально.
Кроме того, у меня есть жест долгого нажатия, который "блокирует" цвет фона, предотвращая вызов 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 ответ
Держите ваши 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()
поскольку у меня нет лишнего кода, но движение работает с изменениями. Если у вас есть другие проблемы, загляните в SimplicityosGesture.