【发布时间】:2022-10-21 04:00:12
【问题描述】:
我有一组相当复杂的视图嵌套在视图中。当我触发一个按钮动作时,我通过我的viewModel 类传递一个可选块,该类在viewModel 上调用objectWillChange.send(),我知道它正在被触发,因为我的视图的其他部分正在更新。其中一个子视图(观察到viewModel 更改)直到我单击其中的一部分(更改viewModel.selectedIndex 并触发重绘,所以我知道它正在侦听已发布的更改)才会更新。
为什么更新不会触发子视图(在本例中为 PurchaseItemGrid)重绘自身?
这是我设置更新调用的地方...
struct RightSideView: View {
@ObservedObject var viewModel: TrenchesPurchases
var body: some View {
VStack {
...
PurchaseItemGrid(viewModel: viewModel) // <-- View not updating
Button {
viewModel.purchaseAction() {
viewModel.objectWillChange.send() // <-- Triggers redraw, reaches breakpoint here
}
} label: {
...
}
...
}
}
}
这是调用可选项的地方(我不仅在视觉上确认这是在视图重绘的其他部分发生时,它还在此处达到断点)...
class TrenchesPurchases: ObservableObject, CanPushCurrency {
// MARK: - Properties
@Published private var model = Purchases()
// MARK: - Properties: Computed
var selectedIndex: Int {
get { return model.selectedIndex }
set { model.selectedIndex = newValue }
}
var purchaseAction: BlockWithBlock {
{ complete in
...
complete?()
}
}
...
}
这是没有按预期更新的视图...
struct PurchaseItemGrid: View {
@ObservedObject var viewModel: TrenchesPurchases
var body: some View {
VStack {
itemRow(indices: 0...3)
...
}
...
}
@ViewBuilder
func itemRow(indices range: ClosedRange<Int>) -> some View {
HStack {
ForEach(viewModel.purchaseItems[range], id: \.id) { item in
PurchaseItemView(item: item,
borderColor: viewModel.selectedIndex == item.id ? .green : Color(Colors.oliveGreen))
.onTapGesture { viewModel.selectedIndex = item.id }
}
}
}
}
这是工作狗要求的代码...
struct Purchases {
// MARK: - Properties
var selectedIndex = 15
let items: [PurchaseItem] = buildCollectionOfItems()
// MARK: - Functions
// MARK: - Functions: Static
// TODO: Define Comments
static func buildCollectionOfItems() -> [PurchaseItem] {
return row0() + row1() + row2() + row3()
}
static func row0() -> [PurchaseItem] {
var items = [PurchaseItem]()
let grenade = Ammo(ammo: .grenade)
items.append(grenade)
let bullets = Ammo(ammo: .bullets)
items.append(bullets)
let infiniteBullets = Unlock(mode: .defense)
items.append(infiniteBullets)
let unlimitedInfantry = Unlock(mode: .offense)
items.append(unlimitedInfantry)
return items
}
static func row1() -> [PurchaseItem] {
var items = [PurchaseItem]()
for unit in UnitType.allCases {
let item = Unit(unit: unit)
items.append(item)
}
return items
}
static func row2() -> [PurchaseItem] {
var items = [PurchaseItem]()
let brits = NationItem(nation: .brits)
items.append(brits)
let turks = NationItem(nation: .turks)
items.append(turks)
let usa = NationItem(nation: .usa)
items.append(usa)
let insane = DifficultyItem(difficulty: .insane)
items.append(insane)
return items
}
static func row3() -> [PurchaseItem] {
var items = [PurchaseItem]()
let offenseLootBox = Random(mode: .offense)
items.append(offenseLootBox)
let defenseLootBox = Random(mode: .defense)
items.append(defenseLootBox)
let currency = Currency(isCheckin: false)
items.append(currency)
let checkIn = Currency(isCheckin: true)
items.append(checkIn)
return items
}
}
【问题讨论】:
-
您是否尝试过仅使用
viewModel.model.selectedIndex = item.id而不是您的var selectedIndex: Int {get..set..}东西。你能告诉我Purchases是什么吗?例如,一个结构体还是一个nestedObservedObject? -
那部分工作正常,它的购买动作块没有触发。 Purchases 是一个单独的结构(不是嵌套的)。
-
如果如你所说,问题与
purchaseAction有关,至少向我们展示它的代码和结构Purchases,这样我们就可以评估发生了什么。 -
我添加了
Purchases代码,但不确定这与发送发布通知的 viewModel 有什么关系。也许这就是我的问题。purchaseAction的代码一直存在,用 cmets 标记,上面写着“触发器重绘,在此处到达断点”。
标签: swift swiftui publisher property-wrapper