首页 > 解决方案 > 过滤的关系计数未在父视图中更新

问题描述

在我的父视图中,我有以下代码:

Text(String((todoList.todoItems as! Set<TodoItem>).filter({ $0.checked }).count))
Text("/")
Text(String(todoList.todoItems?.count ?? 0))

例如,如果我checked完成了 5 个任务中的 2 个,我会得到2/5.

第一个计数(使用过滤器)在todoItems更改时不会更新,但第二个是。如果我完全关闭应用程序并重新打开它,第一个计数确实会显示正确的数字。

当关系发生变化时,如何让第一个数字像第二个一样更新,而无需重新启动应用程序?

标签: iosswiftswiftui

解决方案


这可能不是所需要的,但它会给您一个总体思路。

这是一些示例代码:

import SwiftUI


struct ContentView: View {

    @ObservedObject private var todoList = TodoList()


    var body: some View {
        HStack {
            Text(String(todoList.todoItems?.filter({ $0.checked }).count ?? 0))
            Text("/")
            Text(String(todoList.todoItems?.count ?? 0))
        }
        .onAppear(perform: changeItemAfterSomeSeconds)
    }


    func changeItemAfterSomeSeconds() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
            // Updating
            print("Changed!")
            self.todoList.setChecked(to: true, forIndex: 0)
        }
    }
}



class TodoList: ObservableObject {

    @Published var todoItems: [TodoItem]? = [
        TodoItem(name: "Clean house", checked: false),
        TodoItem(name: "Pay bills", checked: false),
        TodoItem(name: "Exercise", checked: true)
    ]

    func setChecked(to bool: Bool, forIndex index: Int) {
        guard todoItems != nil else { return }
        guard 0 ..< todoItems!.count ~= index else { return }

        let current = todoItems![index]
        guard current.checked != bool else { return }

        todoItems![index] = TodoItem(name: current.name, checked: bool)
    }
}


// Your CoreData class (I don't exactly know what it looks like)
class TodoItem {

    let name: String
    let checked: Bool

    init(name: String, checked: Bool) {
        self.name = name
        self.checked = checked
    }
}

这样做的主要挑战是成为TodoItem一门课程,因为这是您的要求之一。为了实现这一点,setChecked(to:forIndex:)需要做出。

您可以将此代码复制并粘贴到一个空的 SwiftUI 项目中,以查看发生了什么。ContentView因此,在出现3 秒后,changeItemAfterSomeSeconds()执行调用setChecked(to:forIndex:)以更改其值。然后你会看到ContentView更新。

这一切都是通过 using 实现的ObservableObject,这意味着如果@Published属性更改,视图主体应该更新。


推荐阅读