在触发不同的 DragGesture 之前,SwiftUI DragGestures 不会更新
Posted
技术标签:
【中文标题】在触发不同的 DragGesture 之前,SwiftUI DragGestures 不会更新【英文标题】:SwiftUI DragGestures not updating until different DragGesture triggered 【发布时间】: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)
【问题讨论】:
【参考方案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()
,因为我没有额外的代码,但移动与更改一起工作。如果您有其他问题,请查看 SimultaneosGesture。
https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/coordinating_multiple_gesture_recognizers/allowing_the_simultaneous_recognition_of_multiple_gestures
【讨论】:
哦,我明白了。所以本质上我需要定义一个自定义视图,并使用它来存储和显示 Note 类。然后将手势附加到新的自定义视图上。以上是关于在触发不同的 DragGesture 之前,SwiftUI DragGestures 不会更新的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI 中实现触发 switch case 的左或右 DragGesture()?