这里有以下情况。基本上我想根据情况拥有动态数量的选项卡栏项目。在下面提供的示例中,当点击按钮时,它将在数组中间(索引 1)再添加一个选项卡,即先前所在的位置
case .five
。我遇到的问题是,当新的 .three
选项卡显示并且我单击它时,应用程序崩溃并出现以下错误:
"Layout requested for visible navigation bar, <SwiftUI.UIKitNavigationBar: 0x100710c50; baseClass = UINavigationBar; frame = (0 24; 1024 102); opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x600000c63390>; layer = <CALayer: 0x60000026e5a0>> delegate=0x110016200, when the top item belongs to a different navigation bar. topItem = <UINavigationItem: 0x100712790> title='Hello' style=navigator leftItemsSupplementBackButton largeTitleDisplayMode=always, navigation bar = <SwiftUI.UIKitNavigationBar: 0x10951dc00; baseClass = UINavigationBar; frame = (0 24; 1024 102); opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x600000c8b960>; layer = <CALayer: 0x60000028ad60>> delegate=0x10f052800, possibly from a client attempt to nest wrapped navigation controllers."
有趣的是,它只发生在 iOS 17+ 上,而不是 16 上。我收到错误的小 POC:
class ContentViewModel: ObservableObject {
@Published var tabs: [Tab] = [.one, .five]
static var shared = ContentViewModel()
}
struct ContentView: View {
@State var selection: Tab = .one
@StateObject var vm = ContentViewModel.shared
var body: some View {
TabView(selection: $selection) {
ForEach(vm.tabs, id: \.self) { tab in
tab
.tag(tab)
.tabItem {
Text(tab.rawValue)
}
}
}
}
}
enum Tab: String {
case one = "One"
case three = "Three"
case five = "Five"
}
extension Tab: View {
var body: some View {
NavigationStack {
switch self {
case .one:
Text("One")
case .three:
Text("Three")
case .five:
Button("Change") {
if ContentViewModel.shared.tabs.count == 3 {
ContentViewModel.shared.tabs.removeSubrange(1...1)
} else {
ContentViewModel.shared.tabs.insert(.three, at: 1)
}
}
.navigationTitle("Hello")
}
}
}
}
这是几个操作系统之前的一个错误,您应该提交一份报告,以便它再次得到修复,但作为解决方法,您可以为 TabView 设置一个 id。
TabView(selection: $selection) {
ForEach(vm.tabs, id: \.rawValue) { tab in
tab
.tag(tab)
.tabItem {
Text(tab.rawValue)
}
}
}.id(vm.tabs.count) // <——Here
这会重绘整个TabView,因此效率非常低。