SwiftUIとCombineを使用している時に、ObservableObjectの値が素早く変更される時(自分の場合だと初期値が流れる→UserDefaultsを読み込んで値が流れる)に、UIコンポーネントの表示切り替えを if文で行っていると precondition failure: invalid input index: 2
でクラッシュするという問題がありました。
解決方法
現状 if
で分岐してクラッシュを回避するのは難しそうだったので、frameのheightを指定して非表示にするようにしました。(VStackの場合)もし、HStackを使用しているならwidthを指定すればいいと思います。
さらに、Imageなどのコンポーネント自体がサイズを持っている場合は親のサイズを変えても見えてしまう場合があるので、Opacityを0にします。
問題箇所の抜粋
@State private var dataModel = DataModel()
var body: some View {
NavigationView {
VStack {
if dataModel.componentHidden {
SomeComponent()
}
SomeComponent()
}
}
.onReceive(adapter.store.computed.dataModel) { (dataModel) in
self.dataModel = dataModel
}
}
修正後
@State private var dataModel = SupportedCardListTabDataModel()
var body: some View {
NavigationView {
VStack {
SomeComponent()
.frame(height: dataModel.isAdvertiseHidden ? .zero : nil)
.opacity(dataModel.isAdvertiseHidden ? .zero : 1)
SomeComponent()
}
}
.onReceive(adapter.store.computed.dataModel) { (dataModel) in
self.dataModel = dataModel
}
}