1

如果变量来自数组,则标签不会自动刷新。有什么具体原因吗?

@State private var categories: [ItemCategory] = getCategories()
@State private var isOn = true
Button(action: {
    categories[1].chose = !categories[1].chose
}, label: {
    Text(categories[1].chose ? "Add" : "Remove") // not automatically refreshed, only with view change (go to an other and then back)
})

Button(action: {
    isOn = !isOn
}, label: {
    Text(isOn ? "Add" : "Remove") // automatically refreshed
})

更新:

抱歉,我错过了 ItemCategory

class ItemCategory: Codable, Equatable, Identifiable, Hashable {
    var name: String
    var items: [Item]
    var chose: Bool
    var collapsed: Bool
}
4

3 回答 3

1

出现问题是因为ItemCategory是一个。每当您更改其属性时,该对象都保持不变。属性包装器会在包装对象更改时做出反应,而@State不是仅在其属性更改时做出反应。

在这里,您可以找到有关classstruct之间区别的更多信息:


解决您的问题的最简单方法是更改ItemCategory​​为结构(也可能更改Item):

struct ItemCategory: Codable, Equatable, Identifiable, Hashable {
    var name: String
    var items: [Item]
    var chose: Bool
    var collapsed: Bool

    // ...
}

或者,如果您想ItemCategory保留一个class,您可以删除 category 对象并将其再次插入到集合中:

Button(action: {
    let category = categories.remove(at: 1)
    category.chose.toggle()
    categories.insert(category, at: 1)
}, label: {
    Text(categories[1].chose ? "Add" : "Remove")
})
于 2021-03-04T23:26:53.387 回答
0

用于刷新 UI(观察值并对其进行更新)

import Combine

创建预览:

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(list: CategoryList())
    }
}

为类别创建自定义模型类

class ItemCategory {
     var chose: Bool = false
}

为类别创建模型结构,不需要发送对象更改通知

struct ItemCategory {
    var chose: Bool = false
}

创建一个静态列表数组观察值(您可以分配数据列表)

class CategoryList: ObservableObject {
    @Published var items = [ItemCategory(),ItemCategory()]
}

通过在内容视图中观察来更新按钮文本

struct ContentView: View {
    @ObservedObject var list: CategoryList
    var body: some View {
        Button(action: {
            list.items[1].chose = !list.items[1].chose
            /// If using a custom model as class, then we have to send notification to update otherwise commenting this line
            list.objectWillChange.send() // send manually update notification cos class is not auto update support
        }, label: {
            Text(list.items[1].chose ? "Add" : "Remove")
        })
    }
}
于 2021-03-04T11:43:20.267 回答
0

更好 - 使用状态对象

@StateObject var categories: Categories = ...

在哪里:

class Categories : ObservableObject {
    @Published var list: [ItemCategory] = []
    init() {...}

    update(index: Int, row: ItemCategory) {
        self.objectWillChange.send()

        list[index] = row
    }
}

并从@Published 更新视图:

objectWillChange.send()

您可以在视图中进行更改:

Button(action: {
    categories.objectWillChange.send()

    categories.list[1].chose = !categories.list[1].chose
}, label: {
    Text(categories[1].chose ? "Add" : "Remove") // not automatically refreshed, only with view change (go to an other and then back)
})
于 2021-03-04T03:53:37.280 回答