如何解决为什么我的 SwiftUI 列表选择在选择时没有突出显示?
我知道代码不是最漂亮的,我仍在学习压缩代码并减少所需行数的方法,例如我对列表进行排序的方式。但是,我确实需要帮助试图弄清楚为什么这个列表没有在选择的任何行上显示突出显示。作为参考,我放了一条打印语句来验证在行上注册了抽头,并且工作正常。
更多信息:该行的“onDelete”操作正在删除错误的行。也许这与选择有关?任何建议都会很棒。
//
// TableView.swift
// TableDemo (iOS)
//
// Created by Kyle Carroll on 7/20/21.
//
//Todo: Delete at "index set" is deleting wrong row
//Todo: Row selection not working
import SwiftUI
struct TableView: View {
@StateObject var bookStore : BookStore = BookStore(books:bookData)
@State var sortBy: String = ""
@State var IDbuttonStatus: IDButtonStatus = .firstPress
@State var titleButtonStatus: TitleButtonStatus = .firstPress
@State var authorButtonStatus: AuthorButtonStatus = .firstPress
@State var pagesButtonStatus: PagesButtonStatus = .firstPress
enum IDButtonStatus {
case secondPress
case firstPress
var nextStatus: IDButtonStatus {
switch self {
case .firstPress: return .secondPress
case .secondPress: return .firstPress
}
}
var order: String {
switch self {
case .firstPress: return "id2"
case .secondPress: return "id"
}
}
}
enum TitleButtonStatus {
case firstPress
case secondPress
var nextStatus: TitleButtonStatus {
switch self {
case .firstPress: return .secondPress
case .secondPress: return .firstPress
}
}
var order: String {
switch self {
case .firstPress: return "title2"
case .secondPress: return "title"
}
}
}
enum AuthorButtonStatus {
case firstPress
case secondPress
var nextStatus: AuthorButtonStatus {
switch self {
case .firstPress: return .secondPress
case .secondPress: return .firstPress
}
}
var order: String {
switch self {
case .firstPress: return "author2"
case .secondPress: return "author"
}
}
}
enum PagesButtonStatus {
case firstPress
case secondPress
var nextStatus: PagesButtonStatus {
switch self {
case .firstPress: return .secondPress
case .secondPress: return .firstPress
}
}
var order: String {
switch self {
case .firstPress: return "pages2"
case .secondPress: return "pages1"
}
}
}
var body: some View {
vstack {
HStack(alignment: .center,spacing: nil) {
HStack {
Text("ID")
Button {
IDbuttonStatus = IDbuttonStatus.nextStatus
self.sortBy = IDbuttonStatus.order
} label: {
Image(systemName: "chevron.up.chevron.down")
.foregroundColor(Color.black)
}
}
.frame(maxWidth: 50,alignment: .leading)
Divider()
HStack {
Text("Title")
Button {
titleButtonStatus = titleButtonStatus.nextStatus
self.sortBy = titleButtonStatus.order
} label: {
Image(systemName: "chevron.up.chevron.down")
.foregroundColor(Color.black)
}
}
.frame(maxWidth: 200,alignment: .leading)
Divider()
HStack {
Text("Author")
Button {
authorButtonStatus = authorButtonStatus.nextStatus
self.sortBy = authorButtonStatus.order
} label: {
Image(systemName: "chevron.up.chevron.down")
.foregroundColor(Color.black)
}
}
.frame(maxWidth: 200,alignment: .leading)
Divider()
HStack {
Text("Pages")
Button {
pagesButtonStatus = pagesButtonStatus.nextStatus
self.sortBy = pagesButtonStatus.order
} label: {
Image(systemName: "chevron.up.chevron.down")
.foregroundColor(Color.black)
}
}
.frame(maxWidth: 75,alignment: .leading)
}
.frame(maxWidth: .infinity,maxHeight: 40,alignment: .leading)
.padding(.leading,20)
List {
switch self.sortBy {
case "title":
ForEach (bookStore.books.sorted {$0.title < $1.title}) { book in
ListCell(book: book)
}
.onDelete(perform: deleteItems)
case "title2":
ForEach (bookStore.books.sorted {$0.title > $1.title}) { book in
ListCell(book: book)
}
case "id":
ForEach (bookStore.books.sorted {$0.id < $1.id}) { book in
ListCell(book: book)
}
case "id2":
ForEach (bookStore.books.sorted {$0.id > $1.id}) { book in
ListCell(book: book)
}
case "author":
ForEach (bookStore.books.sorted {$0.authorsort < $1.authorsort}) { book in
ListCell(book: book)
}
case "author2":
ForEach (bookStore.books.sorted {$0.authorsort > $1.authorsort}) { book in
ListCell(book: book)
}
case "pages":
ForEach (bookStore.books.sorted {$0.pages < $1.pages}) { book in
ListCell(book: book)
}
case "pages2":
ForEach (bookStore.books.sorted {$0.pages > $1.pages}) { book in
ListCell(book: book)
}
default:
ForEach (bookStore.books.sorted {$0.id < $1.id}) { book in
ListCell(book: book)
}
}
}
.listStyle(PlainListStyle())
.frame(maxWidth: .infinity,alignment: .leading)
}
}
func deleteItems(at offsets: IndexSet) {
bookStore.books.remove(atOffsets: offsets)
}
}
struct ListCell: View {
var book : Book
var body: some View {
HStack(alignment: .center,spacing: nil) {
Text("\(book.id)")
.frame(maxWidth: 50,alignment: .leading)
Divider()
Text(book.title)
.frame(maxWidth: 200,alignment: .leading)
Divider()
Text(book.author)
.frame(maxWidth: 200,alignment: .leading)
Divider()
Text("\(book.pages)")
.frame(maxWidth: 75,alignment: .leading)
}
.onTapGesture {
print(book.title)
}
}
}
struct TableView_Previews: PreviewProvider {
static var previews: some View {
if #available(iOS 15.0,*) {
TableView()
.previewInterfaceOrientation(.landscapeLeft)
} else {
// Fallback on earlier versions
}
}
}
解决方法
“...为什么此列表未在所选行上突出显示。” 我不确定,但很容易修复。查看测试代码。
类似地,“...该行的“onDelete”操作正在删除错误的行。 您必须按照正文对书籍列表进行排序,才能获得要删除的正确索引。 你需要在这方面做一些工作。
这是我用于测试并帮助您前进的代码:
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct TableView: View {
@StateObject var bookStore : BookStore = BookStore() // <--- for testing
@State var sortBy: String = ""
@State var IDbuttonStatus: IDButtonStatus = .firstPress
@State var titleButtonStatus: TitleButtonStatus = .firstPress
@State var authorButtonStatus: AuthorButtonStatus = .firstPress
@State var pagesButtonStatus: PagesButtonStatus = .firstPress
@State var selectedBook: Book? = nil // <---- here
enum IDButtonStatus {
case secondPress
case firstPress
var nextStatus: IDButtonStatus {
switch self {
case .firstPress: return .secondPress
case .secondPress: return .firstPress
}
}
var order: String {
switch self {
case .firstPress: return "id2"
case .secondPress: return "id"
}
}
}
enum TitleButtonStatus {
case firstPress
case secondPress
var nextStatus: TitleButtonStatus {
switch self {
case .firstPress: return .secondPress
case .secondPress: return .firstPress
}
}
var order: String {
switch self {
case .firstPress: return "title2"
case .secondPress: return "title"
}
}
}
enum AuthorButtonStatus {
case firstPress
case secondPress
var nextStatus: AuthorButtonStatus {
switch self {
case .firstPress: return .secondPress
case .secondPress: return .firstPress
}
}
var order: String {
switch self {
case .firstPress: return "author2"
case .secondPress: return "author"
}
}
}
enum PagesButtonStatus {
case firstPress
case secondPress
var nextStatus: PagesButtonStatus {
switch self {
case .firstPress: return .secondPress
case .secondPress: return .firstPress
}
}
var order: String {
switch self {
case .firstPress: return "pages2"
case .secondPress: return "pages1"
}
}
}
var body: some View {
VStack {
HStack(alignment: .center,spacing: nil) {
HStack {
Text("ID")
Button {
IDbuttonStatus = IDbuttonStatus.nextStatus
self.sortBy = IDbuttonStatus.order
} label: {
Image(systemName: "chevron.up.chevron.down")
.foregroundColor(Color.black)
}
}
.frame(maxWidth: 50,alignment: .leading)
Divider()
HStack {
Text("Title")
Button {
titleButtonStatus = titleButtonStatus.nextStatus
self.sortBy = titleButtonStatus.order
} label: {
Image(systemName: "chevron.up.chevron.down")
.foregroundColor(Color.black)
}
}
.frame(maxWidth: 200,alignment: .leading)
Divider()
HStack {
Text("Author")
Button {
authorButtonStatus = authorButtonStatus.nextStatus
self.sortBy = authorButtonStatus.order
} label: {
Image(systemName: "chevron.up.chevron.down")
.foregroundColor(Color.black)
}
}
.frame(maxWidth: 200,alignment: .leading)
Divider()
HStack {
Text("Pages")
Button {
pagesButtonStatus = pagesButtonStatus.nextStatus
self.sortBy = pagesButtonStatus.order
} label: {
Image(systemName: "chevron.up.chevron.down")
.foregroundColor(Color.black)
}
}
.frame(maxWidth: 75,alignment: .leading)
}
.frame(maxWidth: .infinity,maxHeight: 40,alignment: .leading)
.padding(.leading,20)
List {
switch self.sortBy {
case "title":
ForEach (bookStore.books.sorted {$0.title < $1.title}) { book in
ListCell(book: book,selectedBook: $selectedBook) // <---- here
}
.onDelete(perform: deleteItems)
case "title2":
ForEach (bookStore.books.sorted {$0.title > $1.title}) { book in
ListCell(book: book,selectedBook: $selectedBook) // <---- here
}
case "id":
ForEach (bookStore.books.sorted {$0.id < $1.id}) { book in
ListCell(book: book,selectedBook: $selectedBook) // <---- here
}
case "id2":
ForEach (bookStore.books.sorted {$0.id > $1.id}) { book in
ListCell(book: book,selectedBook: $selectedBook) // <---- here
}
case "author":
ForEach (bookStore.books.sorted {$0.authorsort < $1.authorsort}) { book in
ListCell(book: book,selectedBook: $selectedBook) // <---- here
}
case "author2":
ForEach (bookStore.books.sorted {$0.authorsort > $1.authorsort}) { book in
ListCell(book: book,selectedBook: $selectedBook) // <---- here
}
case "pages":
ForEach (bookStore.books.sorted {$0.pages < $1.pages}) { book in
ListCell(book: book,selectedBook: $selectedBook) // <---- here
}
case "pages2":
ForEach (bookStore.books.sorted {$0.pages > $1.pages}) { book in
ListCell(book: book,selectedBook: $selectedBook) // <---- here
}
default:
ForEach (bookStore.books.sorted {$0.id < $1.id}) { book in
ListCell(book: book,selectedBook: $selectedBook) // <---- here
}
}
}
.listStyle(PlainListStyle())
.frame(maxWidth: .infinity,alignment: .leading)
}
}
func deleteItems(at offsets: IndexSet) { // <---- here
// // must sort the bookStore.books as in the body
// let sortedList = ...
// // get the book from the sortedList
// let theBook = sortedList[offsets.first!]
// // get the index of theBook from the bookStore,and remove it
// if let ndx = bookStore.books.firstIndex(of: theBook) {
// withAnimation {
// bookStore.books.remove(at: ndx)
// }
// }
}
}
struct ListCell: View {
var book : Book
@Binding var selectedBook: Book? // <---- here
var body: some View {
HStack(alignment: .center,spacing: nil) {
Text("\(book.id)")
.frame(maxWidth: 50,alignment: .leading)
Divider()
Text(book.title)
.frame(maxWidth: 200,alignment: .leading)
Divider()
Text(book.author)
.frame(maxWidth: 200,alignment: .leading)
Divider()
Text("\(book.pages)")
.frame(maxWidth: 75,alignment: .leading)
}
.background((selectedBook?.id ?? -1) == book.id ? Color.gray : Color.white) // <---- here
.onTapGesture {
print(book.title)
selectedBook = book // <---- here
}
}
}
struct TableView_Previews: PreviewProvider {
static var previews: some View {
if #available(iOS 15.0,*) {
TableView()
.previewInterfaceOrientation(.landscapeLeft)
} else {
// Fallback on earlier versions
}
}
}
struct Book: Identifiable,Hashable {
var id : Int
var title : String
var pages : String
var authorsort : String
var author : String = "author"
}
class BookStore: ObservableObject {
@Published var books: [Book] = [
Book(id: 1,title: "book1",pages: "page1",authorsort: "authorsort1"),Book(id: 2,title: "book2",pages: "page2",authorsort: "authorsort2"),Book(id: 3,title: "book3",pages: "page3",authorsort: "authorsort3")]
}
struct ContentView: View {
var body: some View {
TableView()
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。