![](/img/trans.png)
[英]Why sometimes my selection doesn't get highlighted in macOS SwiftUI List after I've added an item when List items are stored through @AppStorage
[英]Why is my SwiftUI List selection not highlighting when selected?
我知道代码不是最漂亮的,我仍在学习压缩代码并减少所需行数的方法,例如我对列表进行排序的方式。 但是,我确实需要帮助试图弄清楚为什么这个列表没有在选择的任何行上显示突出显示。 作为参考,我放了一个打印语句来验证在行上注册了水龙头,并且它工作正常。
一些进一步的信息:该行的“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()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.