繁体   English   中英

为什么我的 SwiftUI 列表选择在选择时没有突出显示?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM