swift - 如何使用 SwiftUI 制作可滑动 View

标签 swift swiftui

我尝试制作一个 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/

相关文章:

用于复杂设计和架构的 IOS 静态库

Swift:按自定义顺序按键对字典进行排序

ios - 如何在 SwiftUI 中与 GeometryReader 正确对齐

swift - TabView Swift UI 中的 NavigationView

ios - 是否可以在 SwiftUI 中对某个路径上的 View 进行动画处理

macos - macOS 下 SwiftUI 增加模糊半径时是否可以去除四个边缘周围的黑色效果?

ios - 插入单元格后,Stackview 隐藏在可重用的表格 View 单元格中

ios - 导航栏不隐藏

swift - 获取以米为单位的 SCNNode 边界大小

accessibility - Catalyst 'SwiftUI.AccessibilityNode' 不是已知的可序列化元素