使用具有不同ToolbarItem放置的视图时,应用程序崩溃。下面是一个代码段,可让您重现崩溃。
行为
我使用3个视图,每个视图都有自己定义的工具栏。 homeView
和profileView
具有相同的工具栏结构。他们每个人都使用ToolbarItem,其位置为.bottomBar
。另一方面,addView
在工具栏上的动作`.cancellationAction'上有一个ToolbarItem。
按下ToolbarItem时,将更改ViewModel中的viewState
。这会导致当前显示的视图发生更改。
错误消息:
[error] precondition failure: invalid attribute id: 70981 AttributeGraph precondition failure: invalid attribute id: 70981.
目标
iPhone X 14.0(18A373)
代码段:
import SwiftUI
struct SomeView: View {
@ObservedObject var viewModel = ViewModel()
var body: some View {
NavigationView() {
content
}
}
private var content: AnyView {
switch(viewModel.viewState) {
case .home: return AnyView(homeView());
case .add: return AnyView(addView());
case .profile: return AnyView(profileView());
}
}
func homeView() -> some View {
Text("Home View")
.toolbar {
ToolbarItem(placement: .bottomBar) {
HStack {
Button("Home", action: { viewModel.setViewState(state: .home) })
Button("Add", action: { viewModel.setViewState(state: .add) })
Button("Profile", action: { viewModel.setViewState(state: .profile) })
}
}
}
}
func addView() -> some View {
Text("Add View")
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cancel", action: { viewModel.setViewState(state: .home)})
}
}
}
func profileView() -> some View {
Text("Profile View")
.toolbar {
ToolbarItem(placement: .bottomBar) {
HStack {
Button("Home", action: { viewModel.setViewState(state: .home) })
Button("Add", action: { viewModel.setViewState(state: .add) })
Button("Profile", action: { viewModel.setViewState(state: .profile) })
}
}
}
}
}
// MARK: View Model
extension SomeView {
class ViewModel: ObservableObject {
@Published var viewState: ViewState
enum ViewState {
case home, add, profile
}
init() {
self.viewState = .home
}
func setViewState(state: ViewState) {
self.viewState = state;
}
}
}
// MARK: Preview
struct SomeView_Previews: PreviewProvider {
static var previews: some View {
SomeView()
}
}
答案 0 :(得分:1)
是的,对我来说似乎是个错误。
可能的解决方法是将每个视图放在单独的NavigationView
中:
struct ContentView: View {
@ObservedObject var viewModel = ViewModel()
var body: some View {
content
}
@ViewBuilder
var content: some View {
switch viewModel.viewState {
case .home: NavigationView { homeView() }
case .add: NavigationView { addView() }
case .profile: NavigationView { profileView() }
}
}
...
}
或者,您可以将bottomBar添加到addView
:
func addView() -> some View {
Text("Add View")
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cancel", action: { viewModel.setViewState(state: .profile) })
}
ToolbarItem(placement: .bottomBar) {
Text("")
}
}
}
或仅将addView
显示为sheet
。