带NavigationStack的动态尺寸Sheet无法正确调整大小问题
开发包含NavigationStack的Sheet时,动态修改其高度后,视图无法正常展示内容,只有滚动Sheet后内容才会正确显示。
代码示例
struct SheetWithNavigation: View { @EnvironmentObject var router: Router @State private var sheetDetents: Set<PresentationDetent> = [.height(460)] var body: some View { NavigationStack(path: $router.navigation) { VStack { Spacer() Text("Sheet Presented") Spacer() Button("Navigate to First View") { router.navigate(to: .firstNavigationView) } } .navigationDestination(for: Router.Destination.self) { destination in switch destination { case .firstNavigationView: FirstNavigationView() .navigationBarBackButtonHidden(true) .onAppear { sheetDetents = [.height(300)] } } } } .background(.white) .presentationDetents(sheetDetents) } } struct FirstNavigationView: View { var body: some View { VStack { Spacer() Text("First Navigation View") Spacer() Button("Go to second navigation view") {} } .background(.white) } }
解决方案
这个问题源于Sheet高度变化后,NavigationStack内部的视图布局未及时刷新,导致内容位置计算错误。以下是两种可行的修复方式:
方法1:通过修改ID强制刷新NavigationStack
给NavigationStack绑定一个动态ID,当Sheet高度变化时更新ID,触发视图重建,确保布局重新计算:
struct SheetWithNavigation: View { @EnvironmentObject var router: Router @State private var sheetDetents: Set<PresentationDetent> = [.height(460)] @State private var navStackRefreshId = UUID() var body: some View { NavigationStack(path: $router.navigation) { VStack { Spacer() Text("Sheet Presented") Spacer() Button("Navigate to First View") { router.navigate(to: .firstNavigationView) } } .navigationDestination(for: Router.Destination.self) { destination in switch destination { case .firstNavigationView: FirstNavigationView() .navigationBarBackButtonHidden(true) .onAppear { sheetDetents = [.height(300)] } } } } .background(.white) .presentationDetents(sheetDetents) .id(navStackRefreshId) .onChange(of: sheetDetents) { _ in navStackRefreshId = UUID() } } }
方法2:用动画包裹高度修改触发布局更新
在修改Sheet高度时使用withAnimation,让SwiftUI自动处理布局过渡,确保内容正确适配新高度:
FirstNavigationView() .navigationBarBackButtonHidden(true) .onAppear { withAnimation { sheetDetents = [.height(300)] } }
同时,建议检查目标视图的布局逻辑,避免过度依赖Spacer导致的布局自适应问题,必要时给内容添加明确的尺寸约束。
内容的提问来源于stack exchange,提问作者DiegoQ
相关产品推荐
相关产品推荐

