Swift 如果变量在数组中,则不刷新按钮标签
如果变量来自数组,则标签不会自动刷新。有没有具体的原因Swift 如果变量在数组中,则不刷新按钮标签,swift,swiftui,Swift,Swiftui,如果变量来自数组,则标签不会自动刷新。有没有具体的原因 @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" : &q
@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
})
更新:
对不起,我错过了商品分类
class ItemCategory: Codable, Equatable, Identifiable, Hashable {
var name: String
var items: [Item]
var chose: Bool
var collapsed: Bool
}
更好地使用状态对象
@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)
})
用于刷新UI(观察值并在其上更新)
创建预览:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(list: CategoryList())
}
}
为类别创建自定义模型类
class ItemCategory {
var chose: Bool = false
}
或为类别创建模型结构,无需发送对象更改通知
struct ItemCategory {
var chose: Bool = false
}
创建静态列表数组观察值(您可以指定数据列表)
在内容视图中观察按钮文本更新
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")
})
}
}
出现此问题的原因是
itemcegory
是一个类。无论何时更改其属性,对象都保持不变。@State
属性包装器在包装的对象更改时做出反应,而不仅仅是在其属性更改时
在这里,您可以找到有关类和结构之间差异的更多信息:
解决问题的最简单方法是将
itemcegory
更改为结构(也可能更改Item
):
或者,如果希望itemcegory
保持类,可以删除category对象并将其再次插入到集合中:
Button(action: {
let category = categories.remove(at: 1)
category.chose.toggle()
categories.insert(category, at: 1)
}, label: {
Text(categories[1].chose ? "Add" : "Remove")
})
它一定在工作,你的代码没有问题,你能显示ItemCategory的结构吗?如果没有它,就不可能帮助你进行故障排除。
ItemCategory
是一个类吗?请为其添加代码。Itemcategory结构还是类?如果它是一个类,它就不能与@State包装器一起工作。更改为ObservedObject包装。为什么同时使用objectWillChange.send()和@published来观察一个属性?另外,在附加到数组之前调用objectWillChange.send()。
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")
})
}
}
struct ItemCategory: Codable, Equatable, Identifiable, Hashable {
var name: String
var items: [Item]
var chose: Bool
var collapsed: Bool
// ...
}
Button(action: {
let category = categories.remove(at: 1)
category.chose.toggle()
categories.insert(category, at: 1)
}, label: {
Text(categories[1].chose ? "Add" : "Remove")
})