在 SwiftUI 中对分组列表中的项目重新排序

问题描述 投票:0回答:1

我在 SwiftUI 中有一个任务列表视图:

struct TaskListView: View {

@EnvironmentObject var listViewModel: ListViewModel

var body: some View {
    ZStack {
        if listViewModel.items.isEmpty {
            Text("No items")
        } else {
            List {
                ForEach(listViewModel.filteredItems){
                    item in ListRowView(item: item)
                        .onTapGesture {
                            withAnimation(.linear){
                                listViewModel.updateItem(item: item)
                            }
                        }
                }
                .onDelete(perform: listViewModel.deleteItem)
                .onMove(perform: listViewModel.moveItem)
                                    
            }.listStyle(.sidebar)
        }
    }
    //.navigationTitle()
        .navigationBarItems(
            leading: EditButton(),
            trailing: NavigationLink("Add", destination: AddView()))
}}

struct ListRowView: View {
let item: ItemModel
var body: some View {
    HStack {
        Image(systemName: item.isCompleted ? "checkmark.circle": "circle")
            .foregroundColor(item.isCompleted ? .green: .red)
        Text(item.title)
        Spacer()
    }.font(.body)//.title2)
        .padding(.vertical,4)//8)
}}

具有以下视图模型:

class ListViewModel: ObservableObject {
@Published var items: [ItemModel] = [] {
    didSet {
        saveItems()
    }
}

var filteredItems: [ItemModel] {
    items.filter { $0.partOfDay.rawValue.contains("morning")}
}

let itemsKey: String = "items_list"

init() {
    getItems()
}

func getItems() {
    guard
        let data = UserDefaults.standard.data(forKey: itemsKey),
        let savedItems = try? JSONDecoder().decode([ItemModel].self, from: data)
    else { return }
    self.items = savedItems
}

func deleteItem(indexSet: IndexSet) {
    items.remove(atOffsets: indexSet)
}

func moveItem(from: IndexSet, to: Int) {
    items.move(fromOffsets: from, toOffset: to)
}

func addItem(title: String, partOfDay: PartOfDay) {
    let newItem = ItemModel(title: title, partOfDay: partOfDay, isCompleted: false)
    items.append(newItem)
}

func updateItem(item: ItemModel) {
    if let index = items.firstIndex { (existingItem) -> Bool in
        return existingItem.id == item.id
    } {
        items[index] = item.updateCompletion()
    }
}

func saveItems() {
    if let encodedData = try? JSONEncoder().encode(items) {
        UserDefaults.standard.setValue(encodedData, forKey: itemsKey)
    }
}}

我正在尝试对列表中已过滤的项目重新排序,但它不起作用 - 项目恢复到之前的顺序。如果我显示模型中的所有项目而不进行过滤(已发布的属性),则重新排序可以正常工作。如何重新排序已过滤的项目? (我的列表必须按白天的部分进行分组 - 早上、下午、晚上和晚上)

ios swiftui swiftui-list
1个回答
0
投票

在 SwiftUI 中,最好您的类仅用于模型数据。对于视图数据,请使用

View
结构,即用于模型数据的各种视觉表示、排序、移动、过滤等。要过滤项目,您只需创建一个计算变量:

struct ItemsView: View {
    @EnvironmentObejct var store: ModelStore

    @State var searchTerm = "morning"

    var filteredItems: [ItemModel] {
        store.items.filter { item in
            item.partOfDay.contains(searchTerm)
        }
    }

对于没有物品的情况,一个巧妙的技巧是

.overlay
,例如

List(filteredItems) { item in
    ...
}
.overlay {
    if store.items.isEmpty {
        Text("No items")
    }
} 
© www.soinside.com 2019 - 2024. All rights reserved.