我尝试制作一个 SWIFTUI 视图,通过使用gesture() 方法允许卡进行类似刷卡的操作。但我无法找到一种方法来使视图一个接一个地滑动。目前,当我滑动时,所有视图都消失了
import SwiftUI
struct EventView: View {
@State private var offset: CGSize = .zero
@ObservedObject var randomView: EventViewModel
var body: some View {
ZStack{
ForEach(randomView.randomViews,id:\.id){ view in
view
.background(Color.randomColor)
.cornerRadius(8)
.shadow(radius: 10)
.padding()
.offset(x: self.offset.width, y: self.offset.height)
.gesture(
DragGesture()
.onChanged { self.offset = $0.translation }
.onEnded {
if $0.translation.width < -100 {
self.offset = .init(width: -1000, height: 0)
} else if $0.translation.width > 100 {
self.offset = .init(width: 1000, height: 0)
} else {
self.offset = .zero
}
}
)
.animation(.spring())
}
}
}
}
struct EventView_Previews: PreviewProvider {
static var previews: some View {
EventView(randomView: EventViewModel())
}
}
struct PersonView: View {
var id:Int = Int.random(in: 1...1000)
var body: some View {
VStack(alignment: .center) {
Image("testBtn")
.clipShape(/*@START_MENU_TOKEN@*/Circle()/*@END_MENU_TOKEN@*/)
Text("Majid Jabrayilov")
.font(.title)
.accentColor(.white)
Text("iOS Developer")
.font(.body)
.accentColor(.white)
}.padding()
}
}
Run Code Online (Sandbox Code Playgroud)
有了这段代码,当我滑动时,整个东西就消失了
基本上,您的代码告诉每个视图都遵循偏移量,而实际上您只需要最上面的一个移动。因此,首先我要添加一个保存卡当前索引的变量以及计算其偏移量的方法:
@State private var currentCard = 0
func offset(for i: Int) -> CGSize {
return i == currentCard ? offset : .zero
}
Run Code Online (Sandbox Code Playgroud)
其次,我发现如果我们就这样保留它,在下一个触摸视图上将获得最后一个触摸视图的偏移量(-1000, 0),然后才跳转到正确的位置,所以它看起来就像上一张卡决定返回而不是新的。为了解决这个问题,我添加了一个标记,标记该卡刚刚消失,因此当我们再次触摸它时,它最初会到达正确的位置。通常,我们会在手势.began状态下执行此操作,但我们在 swiftUI 中没有类似的方法,因此唯一执行此操作的位置是.onChanged:
@State private var didJustSwipe = false
DragGesture()
.onChanged {
if self.didJustSwipe {
self.didJustSwipe = false
self.currentCard += 1
self.offset = .zero
} else {
self.offset = $0.translation
}
}
Run Code Online (Sandbox Code Playgroud)
在.onEnded成功的情况下我们分配didJustSwipe = true
所以现在它工作得很好。另外,我建议您将代码分成更小的部分。它不仅可以提高可读性,还可以节省一些编译时间。您没有提供EventViewModel和 的实现randomViews,因此我使用了矩形。这是你的代码:
struct EventView: View {
@State private var offset: CGSize = .zero
@State private var currentCard = 0
@State private var didJustSwipe = false
var randomView: some View {
return Rectangle()
.foregroundColor(.green)
.cornerRadius(20)
.frame(width: 300, height: 400)
.shadow(radius: 10)
.padding()
.opacity(0.3)
}
func offset(for i: Int) -> CGSize {
return i == currentCard ? offset : .zero
}
var body: some View {
ZStack{
ForEach(currentCard..<5, id: \.self) { i in
self.randomView
.offset(self.offset(for: i))
.gesture(self.gesture)
.animation(.spring())
}
}
}
var gesture: some Gesture {
DragGesture()
.onChanged {
if self.didJustSwipe {
self.didJustSwipe = false
self.currentCard += 1
self.offset = .zero
} else {
self.offset = $0.translation
}
}
.onEnded {
let w = $0.translation.width
if abs(w) > 100 {
self.didJustSwipe = true
let x = w > 0 ? 1000 : -1000
self.offset = .init(width: x, height: 0)
} else {
self.offset = .zero
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7295 次 |
| 最近记录: |