首页 > 解决方案 > SwiftUI 跳转菜单(sectionIndexTitles)

问题描述

我有一个按字母顺序排序的带有部分的 SwiftUI 列表。我尝试设置一个跳转菜单/侧边栏来滚动浏览如下部分:

带有跳转菜单的屏幕截图

在 UIKit 中,可以通过设置sectionIndexTitles来实现。但我找不到 SwiftUI 的解决方案。

标签: iosswiftswiftui

解决方案


你可以在 SwiftUI 2.0 中做的是使用 ScrollViewReader。

首先,在您的列表中,每个元素都必须有一个唯一的 ID,它可以是任何可散列的对象。只需使用 .id 修饰符。例如:

List(0..<10) { i in
   Text("Row \(i)")
   .id(i)
}

之后,您可以使用 ScrollViewReader,如下所示:

ScrollViewReader { scroll in
    VStack {
        Button("Jump to row #10") {
             scroll.scrollTo(10)
        }

        List(0..<10) { i in
             Text("Row \(i)")
             .id(i)
        }
     }
  }

因此,在您的情况下,您可以为每个字母部分指定一个 id,因此“a”部分将具有 .id(a) 等。之后,您可以使用已实现的侧边栏并跳转到 ScrollViewReader 中所需的字母部分。

编辑:所以我试图快速做出一个非常简单的解决方案。它并不完美,但可以满足您的目的。随意复制和修改代码:

struct AlphaScroller: View {

let alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]

let sampleItems = ["Apple", "Banana", "Orange"]

var body: some View {
    ScrollView {
        ScrollViewReader{ scroll in
            VStack {
                
                //top character picker with horizontal Scrolling
                ScrollView(.horizontal) {
                    HStack(spacing: 20) {
                        ForEach(alphabet, id: \.self) { char in
                            Button(char){
                                withAnimation {
                                    scroll.scrollTo(char, anchor: .top)
                                }
                            }
                        }
                    }
                }.frame(width: UIScreen.main.bounds.width * 0.8, height: 20)
                
                //list of sections
                ForEach(alphabet, id: \.self){ char in
                    HStack {
                        VStack {
                            Text(char).id(char)
                                .font(.system(size: 30))
                                .padding()
                            
                            ForEach(sampleItems, id: \.self){ item in
                                Text(item)
                                    .padding()
                            }
                            
                            Rectangle()
                                .foregroundColor(.gray)
                                .frame(width: UIScreen.main.bounds.width, height: 1)
                        }
                        Spacer()
                    }
                }
            }
        }
    }
}

}


推荐阅读