使用手势后删除视图和移动内容
Posted
技术标签:
【中文标题】使用手势后删除视图和移动内容【英文标题】:Deleting Views and Shifting Content After Using Gesture 【发布时间】:2021-05-23 09:32:12 【问题描述】:我有一个 VStack,通过 DragGesture()、.rotationEffect() 和 .offset(),可以在屏幕外移动和旋转。 VStack 下面是另一个 VStack。 VStack移出屏幕后,如何删除上面的VStack并将下面的VStack向上移动到上面的VStack原来的位置?
这是一个最小的、可重现的例子:
import SwiftUI
struct Test: View
@State var offset = CGSize.zero
var colWidth: CGFloat
var body: some View
VStack
VStack
Text("A")
.frame(width: colWidth)
.border(Color.black, width: 1)
.rotationEffect(.degrees(Double(offset.width / 5)))
.offset(x: offset.width * 5, y: 0)
.gesture(DragGesture()
.onChanged gesture in
self.offset = gesture.translation
.onEnded _ in
if abs(self.offset.width) > 100
else
self.offset = .zero
)
VStack
Text("B")
.frame(width: colWidth)
.border(Color.black)
struct Test_Previews: PreviewProvider
static var previews: some View
Test(colWidth: 414)
在这种情况下,当 A 移出视野时,我应该如何删除 A 并将 B 移动到 A 的位置?
提前致谢!
【问题讨论】:
【参考方案1】:首先,我会使用ForEach
,因此如果您想添加更多字母(例如“C”),则无需更改代码。
它还使删除变得非常容易。只需rows.remove(at: index)
,下方的VStack
s 就会上移。
struct ContentView: View
@State var offset = CGSize.zero
var colWidth: CGFloat = 414
@State var rows = ["A", "B", "C"]
var body: some View
VStack
ForEach(rows.indices, id: \.self) index in
VStack
Text(rows[index]) /// get the current letter
.frame(width: colWidth)
.border(Color.black, width: 1)
.rotationEffect(.degrees(index != 0 ? 0 : Double(offset.width / 5))) /// only rotate if row is on top (index 0)
.offset(x: index != 0 ? 0 : offset.width * 5, y: 0) /// only offset if row is on top (index 0)
.gesture(DragGesture()
.onChanged gesture in
self.offset = gesture.translation
.onEnded _ in
if abs(self.offset.width) > 100
rows.remove(at: index)
self.offset = .zero
)
结果:
编辑:允许在任意行上滑动以删除
struct ContentView: View
@State var gestureIndex: Int?
@State var offset = CGSize.zero
var colWidth: CGFloat = 414
@State var rows = ["A", "B", "C"]
var body: some View
VStack
ForEach(rows.indices, id: \.self) index in
VStack
Text(rows[index])
.frame(width: colWidth)
.border(Color.black, width: 1)
.rotationEffect(.degrees(gestureIndex == index ? Double(offset.width / 5) : 0)) /// only apply rotation if row is dragged row
.offset(x: gestureIndex == index ? offset.width * 5 : 0, y: 0) /// only apply offset if row is dragged row
.gesture(DragGesture()
.onChanged gesture in
print("change: \(index)")
self.gestureIndex = index
self.offset = gesture.translation
.onEnded _ in
if abs(self.offset.width) > 100
rows.remove(at: index)
self.gestureIndex = nil
self.offset = .zero
)
【讨论】:
非常感谢您的回答 - 这对我帮助很大。如果我想刷 C,我必须刷 A 和 B 才能到达 C。有什么方法可以直接刷 C 或任何其他 VStack?以上是关于使用手势后删除视图和移动内容的主要内容,如果未能解决你的问题,请参考以下文章