swiftui 列表 - 快速滚动

Ste*_*Vet 6 xcode scroll list swiftui

我有一个全屏元素列表。

    VStack{
        List {
           ForEach(books, id: \.id) { book in
             Text(book.title)
               .background(Color.yellow) // text background
               .listRowBackground(Color.blue) // cell background
           }
           .frame(height: UIScreen.main.bounds.height)
         }

    }
    .background(Color.red)
    .edgesIgnoringSafeArea(.all)
Run Code Online (Sandbox Code Playgroud)

滚动时是否可以将每个单元格固定在顶部?我不知道该怎么做。

谢谢你!

Saj*_*obi 1

您可以使用DragGestureScrollViewReader在 SwiftUI 中创建捕捉列表。

我们正在计算移动列表的速度。

在此输入图像描述

这是完整的示例代码:

struct SampleSnappingListView: View {
enum ScrollDirection {
    case up
    case down
    case none
}
@State var scrollDirection: ScrollDirection = .none

var body: some View {
    VStack {
        ScrollViewReader { reader in
            List {
                ForEach(0...20, id:\.self) { index in
                    ZStack {
                        Color((index % 2 == 0) ? .red : .green)
                        VStack {
                            Text("Index \(index)")
                                .font(.title)
                        }
                        .frame(height: UIScreen.main.bounds.height/2)
                    }
                    .clipShape(Rectangle())
                    .id(index)
                    .simultaneousGesture(
                        DragGesture(minimumDistance: 0.0)
                            .onChanged({ dragValue in
                                let isScrollDown = 0 > dragValue.translation.height
                                self.scrollDirection = isScrollDown ? .down : .up
                            })
                            .onEnded { value in
                                let velocity = CGSize(
                                    width:  value.predictedEndLocation.x - value.location.x,
                                    height: value.predictedEndLocation.y - value.location.y
                                )
                                if abs(velocity.height) > 10 {
                                    withAnimation(.easeOut(duration: 0.5)) {
                                        let next = index + (scrollDirection == .down ? 1 : -1)
                                        reader.scrollTo(next, anchor: .top)
                                    }
                                }
                            }
                    )
                    
                }
                .listRowSeparator(.hidden)
                .listRowBackground(Color.clear)
                .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
            }
            .listStyle(.plain)
            
        }
    }
  }
}

struct SampleSnappingListView_Previews: PreviewProvider {
   static var previews: some View {
      NavigationView {
        SampleSnappingListView()
            .navigationTitle("Snapping list")
            .navigationBarTitleDisplayMode(.inline)
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

更新:

由于某种原因,在新的 SwiftUI 版本中,速度的计算方式不同,因此我将其缩小:abs(velocity.height) > 10 。请根据您的项目进行设置