rya*_*nnn 11 uitableview ios swift swiftui
是否可以在右侧有一个带有索引的 List,就像下面 SwiftUI 中的示例一样?
Far*_*ouK 12
看看Federico Zanetello 的这篇教程,它是一个 100% SwiftUI 解决方案。
\n\n完整代码(作者:Federico Zanetello):
\nlet database: [String: [String]] = [\n "iPhone": [\n "iPhone", "iPhone 3G", "iPhone 3GS", "iPhone 4", "iPhone 4S", "iPhone 5", "iPhone 5C", "iPhone 5S", "iPhone 6", "iPhone 6 Plus", "iPhone 6S", "iPhone 6S Plus", "iPhone SE", "iPhone 7", "iPhone 7 Plus", "iPhone 8", "iPhone 8 Plus", "iPhone X", "iPhone Xs", "iPhone Xs Max", "iPhone X\xca\x80", "iPhone 11", "iPhone 11 Pro", "iPhone 11 Pro Max", "iPhone SE 2"\n ],\n "iPad": [\n "iPad", "iPad 2", "iPad 3", "iPad 4", "iPad 5", "iPad 6", "iPad 7", "iPad Air", "iPad Air 2", "iPad Air 3", "iPad Mini", "iPad Mini 2", "iPad Mini 3", "iPad Mini 4", "iPad Mini 5", "iPad Pro 9.7-inch", "iPad Pro 10.5-inch", "iPad Pro 11-inch", "iPad Pro 11-inch 2", "iPad Pro 12.9-inch", "iPad Pro 12.9-inch 2", "iPad Pro 12.9-inch 3", "iPad Pro 12.9-inch 4"\n ],\n "iPod": [\n "iPod Touch", "iPod Touch 2", "iPod Touch 3", "iPod Touch 4", "iPod Touch 5", "iPod Touch 6"\n ],\n "Apple TV": [\n "Apple TV 2", "Apple TV 3", "Apple TV 4", "Apple TV 4K"\n ],\n "Apple Watch": [\n "Apple Watch", "Apple Watch Series 1", "Apple Watch Series 2", "Apple Watch Series 3", "Apple Watch Series 4", "Apple Watch Series 5"\n ],\n "HomePod": [\n "HomePod"\n ]\n]\n\nstruct HeaderView: View {\n let title: String\n\n var body: some View {\n Text(title)\n .font(.title)\n .fontWeight(.bold)\n .padding()\n .frame(maxWidth: .infinity, alignment: .leading)\n }\n}\n\nstruct RowView: View {\n let text: String\n\n var body: some View {\n Text(text)\n .padding()\n .frame(maxWidth: .infinity, alignment: .leading)\n }\n}\n\nstruct ContentView: View {\n let devices: [String: [String]] = database\n\n var body: some View {\n ScrollViewReader { proxy in\n ScrollView {\n LazyVStack {\n devicesList\n }\n }\n .overlay(sectionIndexTitles(proxy: proxy))\n }\n .navigationBarTitle("Apple Devices")\n }\n\n var devicesList: some View {\n ForEach(devices.sorted(by: { (lhs, rhs) -> Bool in\n lhs.key < rhs.key\n }), id: \\.key) { categoryName, devicesArray in\n Section(\n header: HeaderView(title: categoryName)\n ) {\n ForEach(devicesArray, id: \\.self) { name in\n RowView(text: name)\n }\n }\n }\n }\n\n func sectionIndexTitles(proxy: ScrollViewProxy) -> some View {\n SectionIndexTitles(proxy: proxy, titles: devices.keys.sorted())\n .frame(maxWidth: .infinity, alignment: .trailing)\n .padding()\n }\n}\n\nstruct SectionIndexTitles: View {\n let proxy: ScrollViewProxy\n let titles: [String]\n @GestureState private var dragLocation: CGPoint = .zero\n\n var body: some View {\n VStack {\n ForEach(titles, id: \\.self) { title in\n SectionIndexTitle(image: sfSymbol(for: title))\n .background(dragObserver(title: title))\n }\n }\n .gesture(\n DragGesture(minimumDistance: 0, coordinateSpace: .global)\n .updating($dragLocation) { value, state, _ in\n state = value.location\n }\n )\n }\n\n func dragObserver(title: String) -> some View {\n GeometryReader { geometry in\n dragObserver(geometry: geometry, title: title)\n }\n }\n\n func dragObserver(geometry: GeometryProxy, title: String) -> some View {\n if geometry.frame(in: .global).contains(dragLocation) {\n DispatchQueue.main.async {\n proxy.scrollTo(title, anchor: .center)\n }\n }\n return Rectangle().fill(Color.clear)\n }\n\n func sfSymbol(for deviceCategory: String) -> Image {\n let systemName: String\n switch deviceCategory {\n case "iPhone": systemName = "iphone"\n case "iPad": systemName = "ipad"\n case "iPod": systemName = "ipod"\n case "Apple TV": systemName = "appletv"\n case "Apple Watch": systemName = "applewatch"\n case "HomePod": systemName = "homepod"\n default: systemName = "xmark"\n }\n return Image(systemName: systemName)\n }\n}\n\nstruct SectionIndexTitle: View {\n let image: Image\n\n var body: some View {\n RoundedRectangle(cornerRadius: 8, style: .continuous)\n .foregroundColor(Color.gray.opacity(0.1))\n .frame(width: 40, height: 40)\n .overlay(\n image\n .foregroundColor(.blue)\n )\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
我在 SwiftUI 中做到了这一点
//
// Contacts.swift
// TestCalendar
//
// Created by Christopher Riner on 9/11/20.
//
import SwiftUI
struct Contact: Identifiable, Comparable {
static func < (lhs: Contact, rhs: Contact) -> Bool {
return (lhs.lastName, lhs.firstName) < (rhs.lastName, rhs.firstName)
}
var id = UUID()
let firstName: String
let lastName: String
}
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"]
struct Contacts: View {
@State private var searchText = ""
var contacts = [Contact]()
var body: some View {
VStack {
ScrollViewReader { scrollProxy in
ZStack {
List {
SearchBar(searchText: $searchText)
.padding(EdgeInsets(top: 0, leading: -20, bottom: 0, trailing: -20))
ForEach(alphabet, id: \.self) { letter in
Section(header: Text(letter).id(letter)) {
ForEach(contacts.filter({ (contact) -> Bool in
contact.lastName.prefix(1) == letter
})) { contact in
HStack {
Image(systemName: "person.circle.fill").font(.largeTitle).padding(.trailing, 5)
Text(contact.firstName)
Text(contact.lastName)
}
}
}
}
}
.navigationTitle("Contacts")
.listStyle(PlainListStyle())
.resignKeyboardOnDragGesture()
VStack {
ForEach(alphabet, id: \.self) { letter in
HStack {
Spacer()
Button(action: {
print("letter = \(letter)")
//need to figure out if there is a name in this section before I allow scrollto or it will crash
if contacts.first(where: { $0.lastName.prefix(1) == letter }) != nil {
withAnimation {
scrollProxy.scrollTo(letter)
}
}
}, label: {
Text(letter)
.font(.system(size: 12))
.padding(.trailing, 7)
})
}
}
}
}
}
}
}
init() {
contacts.append(Contact(firstName: "Chris", lastName: "Ryan"))
contacts.append(Contact(firstName: "Allyson", lastName: "Ryan"))
contacts.append(Contact(firstName: "Jonathan", lastName: "Ryan"))
contacts.append(Contact(firstName: "Brendan", lastName: "Ryaan"))
contacts.append(Contact(firstName: "Jaxon", lastName: "Riner"))
contacts.append(Contact(firstName: "Leif", lastName: "Adams"))
contacts.append(Contact(firstName: "Frank", lastName: "Conors"))
contacts.append(Contact(firstName: "Allyssa", lastName: "Bishop"))
contacts.append(Contact(firstName: "Justin", lastName: "Bishop"))
contacts.append(Contact(firstName: "Johnny", lastName: "Appleseed"))
contacts.append(Contact(firstName: "George", lastName: "Washingotn"))
contacts.append(Contact(firstName: "Abraham", lastName: "Lincoln"))
contacts.append(Contact(firstName: "Steve", lastName: "Jobs"))
contacts.append(Contact(firstName: "Steve", lastName: "Woz"))
contacts.append(Contact(firstName: "Bill", lastName: "Gates"))
contacts.append(Contact(firstName: "Donald", lastName: "Trump"))
contacts.append(Contact(firstName: "Darth", lastName: "Vader"))
contacts.append(Contact(firstName: "Clark", lastName: "Kent"))
contacts.append(Contact(firstName: "Bruce", lastName: "Wayne"))
contacts.append(Contact(firstName: "John", lastName: "Doe"))
contacts.append(Contact(firstName: "Jane", lastName: "Doe"))
contacts.sort()
}
}
struct Contacts_Previews: PreviewProvider {
static var previews: some View {
Contacts()
}
}
Run Code Online (Sandbox Code Playgroud)
我一直在寻找同一问题的解决方案,但目前我们可能拥有的唯一选择是用作UITableView
视图。
import SwiftUI
import UIKit
struct TableView: UIViewRepresentable {
func makeUIView(context: Context) -> UITableView {
let tableView = UITableView(frame: .zero, style: .plain)
tableView.delegate = context.coordinator
tableView.dataSource = context.coordinator
return tableView
}
func updateUIView(_ uiView: UITableView, context: Context) {
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
final class Coordinator: NSObject, UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellId = "cellIdentifier"
let cell = tableView.dequeueReusableCell(withIdentifier: cellId) ?? UITableViewCell(style: .default, reuseIdentifier: cellId)
cell.textLabel?.text = "\(indexPath)"
return cell
}
func sectionIndexTitles(for tableView: UITableView) -> [String]? {
["a", "b"]
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2470 次 |
最近记录: |