gpt4 book ai didi

ios - 如何检测何时拖动 SwiftUI View

转载 作者:行者123 更新时间:2023-12-04 14:05:10 27 4
gpt4 key购买 nike

当用户在我的 View 上拖动手指时,我想触发动画。
我可以做类似的事情

Image(…)
.rotationEffect(…)
.animation(self.isAnimating ? .spring : .default)
.gesture(
DragGesture(minimumDistance: 5, coordinateSpace: .global)
.onChanged { value in
self.isAnimating = true
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.isAnimating = false
}
}
)
然而,这仅捕获在图像上开始的拖动事件。从别处开始然后在图像上移动的拖动事件将被忽略。
我还可以检测父 View 中的拖动事件并计算哪些 subview 被拖动 - 这很好。但是,我如何告诉 subview 动画呢?更新它们的属性会导致重新渲染,这当然会取消动画。
通过模型传递这样的 ui 数据似乎是一种反模式。
有什么建议?

最佳答案

我用一个小卡片 View 的网格替换了你的例子的图像。
我们将尝试更改通过拖动手势“交叉”的卡片的颜色。
我们可以使用 PreferenceKey获取所有 CardView界...

struct CardPreferenceData: Equatable {
let index: Int
let bounds: CGRect
}

struct CardPreferenceKey: PreferenceKey {
typealias Value = [CardPreferenceData]

static var defaultValue: [CardPreferenceData] = []

static func reduce(value: inout [CardPreferenceData], nextValue: () -> [CardPreferenceData]) {
value.append(contentsOf: nextValue())
}
}

这里 :
struct CardView: View {
let index: Int

var body: some View {
Text(index.description)
.padding(10)
.frame(width: 60)
.overlay(RoundedRectangle(cornerRadius: 10).stroke())
.background(
GeometryReader { geometry in
Rectangle()
.fill(Color.clear)
.preference(key: CardPreferenceKey.self,
value: [CardPreferenceData(index: self.index, bounds: geometry.frame(in: .named("GameSpace")))])
}
)
}
}

现在在 ContentView 中,我们可以收集这些卡片的所有首选项(边界和索引)并将它们存储在一个数组中:
.onPreferenceChange(CardPreferenceKey.self){ value in
cardsData = value
}
我们现在可以将这些 CardView 的位置( bounds)与拖动手势的位置进行比较。

struct ContentView: View {
let columns = Array(repeating: GridItem(.fixed(60), spacing: 40), count: 3)
@State private var selectedCardsIndices: [Int] = []
@State private var cardsData: [CardPreferenceData] = []
var body: some View {
LazyVGrid(columns: columns, content: {
ForEach((1...12), id: \.self) { index in
CardView(index: index)
.foregroundColor(selectedCardsIndices.contains(index) ? .red : .blue)
}
})
.onPreferenceChange(CardPreferenceKey.self){ value in
cardsData = value
}
.gesture(
DragGesture()
.onChanged {drag in
if let data = cardsData.first(where: {$0.bounds.contains(drag.location)}) {
selectedCardsIndices.append(data.index)
}
}
)
.coordinateSpace(name: "GameSpace")
}
}

Example
编辑:视频开头的小“滞后”不会出现在 Canvas 上。只能在模拟器上。我没有在真实设备上测试过。

关于ios - 如何检测何时拖动 SwiftUI View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68785513/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com