WatchOS 在有条件的视图中使用 ObservableObject 导致运行时错误
WatchOS Using ObservableObject in Conditional in View Causing Runtime Error
我用一个ObservableObject
来保持用户是否订阅我的应用程序的状态,并根据订阅状态显示不同的视图。这在 Xcode 13 和 WatchOS 8 之前工作正常,但现在这会导致运行时错误 runtime: SwiftUI: Accessing State's value outside of being installed on a View. This will result in a constant Binding of the initial value and will not update.
并且,绑定不会根据错误更新。这发生在 Xcode 13.1 和 13.2b2
下面的代码重现了错误:
struct MultiPageView: View {
@ObservedObject var subscribed = SubscribedModel.shared
var body: some View {
if subscribed.value {
TabView {
ViewOne()
ViewTwo()
ViewThree()
ToggleView()
}
.tabViewStyle(PageTabViewStyle())
} else {
TabView {
ViewOne()
ToggleView()
}
.tabViewStyle(PageTabViewStyle())
}
}
}
struct ToggleView: View {
@ObservedObject var subscribed = SubscribedModel()
var body: some View {
Toggle(isOn: $subscribed.value) {
Text("Subscribed")
}
}
}
class SubscribedModel: ObservableObject {
public static let shared = SubscribedModel.shared
@Published var value: Bool = false
}
为了简洁起见,我只列出 ViewOne
,但是 ViewTwo
和 ViewThree
是相同的,只是不同的文本:
struct ViewOne: View {
var body: some View {
Text("View One")
.padding()
}
}
如果您导航到 ToggleView()
,然后切换开关,错误会立即弹出。有什么解决这个问题的建议吗?
根据@LoremIpsum 评论更新:
struct MultiPageView: View {
@StateObject var subscribed = SubscribedModel()
var body: some View {
if subscribed.value {
TabView {
ViewOne()
ViewTwo()
ViewThree()
ToggleView(subscribed: $subscribed.value)
}
.tabViewStyle(PageTabViewStyle())
} else {
TabView {
ViewOne()
ToggleView(subscribed: $subscribed.value)
}
.tabViewStyle(PageTabViewStyle())
}
}
}
struct ToggleView: View {
@Binding var subscribed: Bool
var body: some View {
Toggle(isOn: $subscribed) {
Text("Subscribed")
}
}
}
现在正在TabViews
之间切换,但错误仍然存在,并且立即出现。删除了 DerivedData 并清理了构建文件夹。有什么想法吗?
我要补充一点,同样的基本代码在 iOS 15 上 运行 没问题。只是 WatchOS 弹出错误。
我遇到同样的问题很长时间了,在 Xcode 13.2.1.
上仍然发生这种情况
watchOS 上的 TabView
似乎是一个问题,因为如果您将 TabView 替换为另一个视图,错误就会消失。
解决方案是使用 TabView
的初始化程序和 selection
值:init(selection:content:)
1定义一个属性供选择
@State private var selection = 0
2 更新 TabView
来自
TabView {
// content
}
到
TabView(selection: $selection) {
// content
}
更新您的代码如下所示:
struct MultiPageView: View {
@StateObject var subscribed = SubscribedModel()
@State private var selection = 0
var body: some View {
if subscribed.value {
TabView(selection: $selection) {
ViewOne()
ViewTwo()
ViewThree()
ToggleView(subscribed: $subscribed.value)
}
.tabViewStyle(PageTabViewStyle())
} else {
TabView(selection: $selection) {
ViewOne()
ToggleView(subscribed: $subscribed.value)
}
.tabViewStyle(PageTabViewStyle())
}
}
}
基本上只是为 TabView.selection
定义一个 @State
属性,然后在你的两个 TabView 上使用它(使用分离的属性也可以)。
我用一个ObservableObject
来保持用户是否订阅我的应用程序的状态,并根据订阅状态显示不同的视图。这在 Xcode 13 和 WatchOS 8 之前工作正常,但现在这会导致运行时错误 runtime: SwiftUI: Accessing State's value outside of being installed on a View. This will result in a constant Binding of the initial value and will not update.
并且,绑定不会根据错误更新。这发生在 Xcode 13.1 和 13.2b2
下面的代码重现了错误:
struct MultiPageView: View {
@ObservedObject var subscribed = SubscribedModel.shared
var body: some View {
if subscribed.value {
TabView {
ViewOne()
ViewTwo()
ViewThree()
ToggleView()
}
.tabViewStyle(PageTabViewStyle())
} else {
TabView {
ViewOne()
ToggleView()
}
.tabViewStyle(PageTabViewStyle())
}
}
}
struct ToggleView: View {
@ObservedObject var subscribed = SubscribedModel()
var body: some View {
Toggle(isOn: $subscribed.value) {
Text("Subscribed")
}
}
}
class SubscribedModel: ObservableObject {
public static let shared = SubscribedModel.shared
@Published var value: Bool = false
}
为了简洁起见,我只列出 ViewOne
,但是 ViewTwo
和 ViewThree
是相同的,只是不同的文本:
struct ViewOne: View {
var body: some View {
Text("View One")
.padding()
}
}
如果您导航到 ToggleView()
,然后切换开关,错误会立即弹出。有什么解决这个问题的建议吗?
根据@LoremIpsum 评论更新:
struct MultiPageView: View {
@StateObject var subscribed = SubscribedModel()
var body: some View {
if subscribed.value {
TabView {
ViewOne()
ViewTwo()
ViewThree()
ToggleView(subscribed: $subscribed.value)
}
.tabViewStyle(PageTabViewStyle())
} else {
TabView {
ViewOne()
ToggleView(subscribed: $subscribed.value)
}
.tabViewStyle(PageTabViewStyle())
}
}
}
struct ToggleView: View {
@Binding var subscribed: Bool
var body: some View {
Toggle(isOn: $subscribed) {
Text("Subscribed")
}
}
}
现在正在TabViews
之间切换,但错误仍然存在,并且立即出现。删除了 DerivedData 并清理了构建文件夹。有什么想法吗?
我要补充一点,同样的基本代码在 iOS 15 上 运行 没问题。只是 WatchOS 弹出错误。
我遇到同样的问题很长时间了,在 Xcode 13.2.1.
上仍然发生这种情况watchOS 上的 TabView
似乎是一个问题,因为如果您将 TabView 替换为另一个视图,错误就会消失。
解决方案是使用 TabView
的初始化程序和 selection
值:init(selection:content:)
1定义一个属性供选择
@State private var selection = 0
2 更新 TabView
来自
TabView {
// content
}
到
TabView(selection: $selection) {
// content
}
更新您的代码如下所示:
struct MultiPageView: View {
@StateObject var subscribed = SubscribedModel()
@State private var selection = 0
var body: some View {
if subscribed.value {
TabView(selection: $selection) {
ViewOne()
ViewTwo()
ViewThree()
ToggleView(subscribed: $subscribed.value)
}
.tabViewStyle(PageTabViewStyle())
} else {
TabView(selection: $selection) {
ViewOne()
ToggleView(subscribed: $subscribed.value)
}
.tabViewStyle(PageTabViewStyle())
}
}
}
基本上只是为 TabView.selection
定义一个 @State
属性,然后在你的两个 TabView 上使用它(使用分离的属性也可以)。