iOS 16中SwiftUI的NavigationStack与TabView:Bug还是用法不当?
环境:Xcode 14.1、iOS 16.1
问题描述
实现了NavigationStack嵌套TabView的结构,TabView包含两个带ScrollView的页面:
- 点击Tab1后上滑,大导航标题正常居中收缩,页面内容滑至下方并模糊,符合预期;
- 点击Tab2后上滑,大标题无变化,页面内容也不会模糊;切回Tab1后恢复正常。
原代码
ContentView
import SwiftUI struct ContentView: View { @State private var selection: Tab = .tab1 enum Tab { case tab1 case tab2 } @State private var mainTitle = "Tab1" var body: some View { NavigationStack { TabView(selection: $selection) { Tab1(mainTitle: $mainTitle) .tabItem { Label("Tab1", systemImage: "wrench.adjustable.fill") } .tag(Tab.tab1) Tab2(mainTitle: $mainTitle) .tabItem { Label("Tab2", systemImage: "wrench.adjustable.fill") } .tag(Tab.tab2) } .navigationTitle(mainTitle) } } }
Tab1
import SwiftUI struct Tab1: View { @Binding var mainTitle : String var body: some View { ScrollView { Text("Text tab 1") .padding(.all,100) .background(.blue) } .onAppear { mainTitle = "Tab1" } } }
Tab2
import SwiftUI struct Tab2: View { @Binding var mainTitle : String var body: some View { ScrollView { Text("Text tab 2") .padding(.all,100) .background(.green) } .onAppear { mainTitle = "Tab2" } } }
尝试过的无效方案
.onAppear { let tabBarAppearance = UITabBarAppearance() tabBarAppearance.configureWithOpaqueBackground() UITabBar.appearance().scrollEdgeAppearance = tabBarAppearance }
解决方案
问题根源是外层NavigationStack无法在Tab切换时,自动将导航栏的滚动联动关联到新Tab的ScrollView。将NavigationStack移至每个Tab内部,让每个页面拥有独立的导航上下文,即可解决该问题:
修改后的ContentView
import SwiftUI struct ContentView: View { @State private var selection: Tab = .tab1 enum Tab { case tab1 case tab2 } var body: some View { TabView(selection: $selection) { // Tab1独立导航栈 NavigationStack { Tab1() .navigationTitle("Tab1") } .tabItem { Label("Tab1", systemImage: "wrench.adjustable.fill") } .tag(Tab.tab1) // Tab2独立导航栈 NavigationStack { Tab2() .navigationTitle("Tab2") } .tabItem { Label("Tab2", systemImage: "wrench.adjustable.fill") } .tag(Tab.tab2) } } }
修改后的Tab1
import SwiftUI struct Tab1: View { var body: some View { ScrollView { Text("Text tab 1") .padding(.all,100) .background(.blue) } } }
修改后的Tab2
import SwiftUI struct Tab2: View { var body: some View { ScrollView { Text("Text tab 2") .padding(.all,100) .background(.green) } } }
此方案让每个Tab页面的ScrollView与自身的NavigationStack绑定,切换Tab时导航栏的滚动联动会正常触发,标题收缩、内容模糊的效果均能正常工作。
内容的提问来源于stack exchange,提问作者samsamsam
相关产品推荐
相关产品推荐

