ios 检测用户何时在选取器中选取相同值以更改排序顺序

rbl8hiat  于 2023-02-17  发布在  iOS
关注(0)|答案(1)|浏览(138)

我正在尝试在菜单中使用Picker对列表进行排序,如图所示

拣货器工作,分拣工作,缺少的部分是分拣顺序
目标行为:当用户选择排序字段时,排序顺序将为ASC,但当用户再次选择同一字段时,排序顺序应为DES。
我如何检测用户是否在picker中再次选择了相同的字段?或者有更好的方法吗?
谢谢
下面是我示例代码

struct Book: Identifiable {
    let id = UUID()
    let title, author: String
    let sales: Int
}

enum SortField: String, CaseIterable {
    case title, author, sales
}

struct ContentView: View {
    
    @State private var items: [Book] = [
        .init(title: "Da Vinci Code,The", author: "Brown, Dan", sales: 5094805),
        .init(title: "Harry Potter and the Deathly Hallows", author: "Rowling, J.K.", sales: 4475152),
        .init(title: "Angels and Demons", author: "Brown, Dan", sales: 3193946),
        .init(title: "One Day", author: "Nicholls, David", sales: 1616068),
        .init(title: "Billy Connolly", author: "Stephenson, Pamela", sales: 1231957),
    ]
    
    @State private var selectedSortField: SortField = .title
    @State private var ascending: Bool = false
    
    var body: some View {
        NavigationView {
            Form {
                ForEach(items) { item in
                    HStack {
                        VStack(alignment: .leading) {
                            Text(item.title)
                                .font(.headline)
                            Text(item.author)
                        }
                        Spacer()
                        Text("\(item.sales)")
                            .font(.caption)
                    }
                }
            }
            .toolbar {
                Menu {
                    Picker(selection: $selectedSortField, label: Text("Sorting")) {
                        ForEach(SortField.allCases, id: \.self) { field in
                            HStack {
                                Text(field.rawValue)
                                if selectedSortField == field {
                                    Image(systemName: ascending ? "arrow.up" : "arrow.down")
                                }
                            }
                        }
                    }
                    .onChange(of: selectedSortField) { _ in sort() }
                } label: {
                    Label("Menu", systemImage: "ellipsis.circle")
                }
            }
        }
    }
    
    private func sort() {
        switch selectedSortField {
        case .title: items.sort { ascending ? $0.title < $1.title : $0.title > $1.title }
        case .author: items.sort { ascending ? $0.author < $1.author : $0.author > $1.author }
        case .sales: items.sort { ascending ? $0.sales < $1.sales : $0.sales > $1.sales }
        }
    }
    
}
pftdvrlh

pftdvrlh1#

实现这一点的一种方法是在SortField案例中包含ascending标志。

struct Book: Identifiable {
    let id = UUID()
    let title, author: String
    let sales: Int
}

enum SortField: Hashable {
    case title(asc: Bool), author(asc: Bool), sales(asc: Bool)
    
    var title: String {
        switch self {
        case .title: return "Title"
        case .author: return "Author"
        case .sales: return "Sales"
        }
    }
    
    var isAscending: Bool {
        switch self {
        case .title(let asc), .author(let asc), .sales(let asc):
            return asc
        }
    }
    
    var inverse: Self {
        switch self {
        case .title(let asc):
            return .title(asc: !asc)
        case .author(let asc):
            return .author(asc: !asc)
        case .sales(let asc):
            return .sales(asc: !asc)
        }
    }
}

struct ContentView: View {
    
    @State private var items: [Book] = [
        .init(title: "Da Vinci Code,The", author: "Brown, Dan", sales: 5094805),
        .init(title: "Harry Potter and the Deathly Hallows", author: "Rowling, J.K.", sales: 4475152),
        .init(title: "Angels and Demons", author: "Brown, Dan", sales: 3193946),
        .init(title: "One Day", author: "Nicholls, David", sales: 1616068),
        .init(title: "Billy Connolly", author: "Stephenson, Pamela", sales: 1231957),
    ]
    
    @State private var selectedSortField: SortField = .title(asc: true)
    
    var body: some View {
        NavigationView {
            Form {
                ForEach(items) { item in
                    HStack {
                        VStack(alignment: .leading) {
                            Text(item.title)
                                .font(.headline)
                            Text(item.author)
                        }
                        Spacer()
                        Text("\(item.sales)")
                            .font(.caption)
                    }
                }
            }
            .toolbar {
                Menu {
                    Picker(selection: $selectedSortField, label: Text("Sorting")) {
                        ForEach(sortFields, id: \.self) { field in
                            HStack {
                                Text(field.title)
                                if selectedSortField == field || selectedSortField == field.inverse {
                                    Image(systemName: field.isAscending ? "arrow.up" : "arrow.down")
                                }
                            }
                        }
                    }
                    .onChange(of: selectedSortField) { _ in sort() }
                } label: {
                    Label("Menu", systemImage: "ellipsis.circle")
                }
            }
        }
    }
    
    var sortFields: [SortField] {
        var sortFields: [SortField] = []
        if case .title(true) = selectedSortField {
            sortFields.append(.title(asc: false))
        } else {
            sortFields.append(.title(asc: true))
        }
        if case .author(true) = selectedSortField {
            sortFields.append(.author(asc: false))
        } else {
            sortFields.append(.author(asc: true))
        }
        if case .sales(true) = selectedSortField {
            sortFields.append(.sales(asc: false))
        } else {
            sortFields.append(.sales(asc: true))
        }
        return sortFields
    }
    
    private func sort() {
        switch selectedSortField {
        case .title(let ascending): items.sort { ascending ? $0.title < $1.title : $0.title > $1.title }
        case .author(let ascending): items.sort { ascending ? $0.author < $1.author : $0.author > $1.author }
        case .sales(let ascending): items.sort { ascending ? $0.sales < $1.sales : $0.sales > $1.sales }
        }
    }
}

相关问题