我尝试制作一个 SWIFTUI View ,通过使用gesture() 方法允许卡进行类似滑动的操作。但我无法找到一种方法来使 View 一个接一个地滑动。目前,当我滑动时,所有 View 都消失了
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()
}
}
有了这段代码,当我滑动时,整个东西就消失了
最佳答案
基本上,您的代码告诉每个 View 都遵循偏移量,而实际上您只需要最上面的一个移动。因此,首先我要添加一个保存卡当前索引的变量以及一个计算其偏移量的方法:
@State private var currentCard = 0
func offset(for i: Int) -> CGSize {
return i == currentCard ? offset : .zero
}
其次,我发现如果我们就这样保留它,在下一个触摸 View 上将获得最后一个触摸 View 的偏移量(-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
}
}
在.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
}
}
}
}
关于swift - 如何使用 SwiftUI 制作可滑动 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58411990/