我认为SwiftUI应该在数据依赖于更改时自动更新视图。但是,以下代码中没有发生这种情况:
首先,我做一个简单的BindableObject
import SwiftUI
import Combine
class Example: BindableObject {
var didChange = PassthroughSubject<Void, Never>()
var test = 1 {
didSet {
didChange.send(())
}
}
}
然后是应用程序的根视图:
struct BindTest : View {
@Binding var test: Example
var body: some View {
PresentationButton(destination: BindChange(test: $test)) {
ForEach(0..<test.test) { index in
Text("Invalidate Me! \(index)")
}
}
}
}
最后是我更改BindableObject
的值的视图:
struct BindChange : View {
@Binding var test: Example
@Environment(\.isPresented) var isPresented
var body: some View {
Button(action: act) {
Text("Return")
}
}
func act() {
test.test = 2
isPresented?.value = false
}
}
点击返回按钮时,应该有两个Text View实例-但只有1个。我在做什么错了?
还值得注意的是:如果我将@Binding
更改为@EnvironmentObject
,则在您点击产生此错误的按钮时,程序只会崩溃:
线程1:EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0)
下面的完整代码:
import SwiftUI
import Combine
class Example: BindableObject {
var didChange = PassthroughSubject<Example, Never>()
var test = 1 {
didSet {
didChange.send(self)
}
}
static let `default` = {
return Example()
}()
}
//Root View
struct BindTest : View {
@EnvironmentObject var test: Example
var body: some View {
PresentationButton(destination: BindChange()) {
ForEach(0..<test.test) { t in
Text("Invalidate Me! \(t)")
}
}
}
}
//View that changes the value of @Binding / @EnvironmentObject
struct BindChange : View {
@EnvironmentObject var test: Example
@Environment(\.isPresented) var isPresented
var body: some View {
Button(action: act) {
Text("Return")
}
}
func act() {
test.test = 2
isPresented?.value = false
}
}
#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
//ContentView().environmentObject(EntryStore())
BindTest().environmentObject(Example())
}
}
#endif
编辑2:此时的帖子有点混乱,但是EnvironmentObject
的崩溃似乎与PresentationButton
的问题有关
通过将NavigationButton放在NavigationView中,以下代码将产生正确的结果-当List
更改时,test.test
无效:
//Root View
struct BindTest : View {
@EnvironmentObject var test: Example
var body: some View {
NavigationView {
NavigationButton(destination: BindChange()) {
ForEach(0..<test.test) { t in
Text("Functional Button #\(t)")
}
}
}
}
}