微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我知道代码不是最漂亮的,我仍在学习压缩代码并减少所需行数的方法,例如我对列表进行排序的方式。但是,我确实需要帮助试图弄清楚为什么这个列表没有在选择的任何行上显示突出显示。作为参考,我放了一条打印语句来验证在行上注册了抽头,并且工作正常。

更多信息:该行的“onDelete”操作正在删除错误的行。也许这与选择有关?任何建议都会很棒。

Current State

//
//  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 举报,一经查实,本站将立刻删除。