如何阻止SwiftUI后台视图在.sheet全屏展示时收缩?
实现指定区域无收缩动画的全屏Sheet
可以实现,下面是两种适配不同场景的解决方案:
方案1:仅让红色区域跳过收缩动画
如果只需要红色区域(比如顶部导航栏/固定栏)不参与收缩,其他后台内容保留默认动画,可通过分层布局+禁用目标视图动画实现:
@State private var isSheetPresented = false var body: some View { ZStack { // 红色目标区域:禁用动画 Color.red .frame(height: 100) .animation(nil, value: isSheetPresented) // 让该视图无视Sheet弹出的动画触发 // 其他后台内容:保留系统默认收缩动画 ScrollView { VStack(spacing: 20) { ForEach(1...20, id: \.self) { idx in Text("后台内容行 \(idx)") .frame(maxWidth: .infinity) .padding() .background(.gray.opacity(0.2)) } } } .animation(.default, value: isSheetPresented) } .sheet(isPresented: $isSheetPresented) { // 最大高度的Sheet内容 Text("全屏Sheet内容") .frame(maxWidth: .infinity, maxHeight: .infinity) .background(.white) .presentationDetents([.large]) } }
方案2:彻底取消后台内容的收缩动画
如果希望所有后台内容(包括红色区域)都不执行收缩动画,可通过修改Sheet的展示样式实现:
@State private var isSheetPresented = false var body: some View { ZStack { Color.red.frame(height: 100) ScrollView { // 后台内容... } } .sheet(isPresented: $isSheetPresented) { Text("全屏Sheet内容") .frame(maxWidth: .infinity, maxHeight: .infinity) .background(.white) .presentationDetents([.large]) } .presentationModalStyle(.overFullScreen) // 覆盖全屏,不触发背景缩放 .presentationBackgroundInteraction(.enabled) // 允许点击背景关闭Sheet(可选) }
针对导航栏场景的补充
如果红色区域是NavigationStack的导航栏,直接给导航栏禁用动画即可:
NavigationStack { // 页面内容 } .navigationTitle("页面标题") .animation(nil, value: isSheetPresented) // 导航栏不参与Sheet弹出动画 .sheet(isPresented: $isSheetPresented) { // Sheet内容... .presentationDetents([.large]) }
内容的提问来源于stack exchange,提问作者Konstantin.Efimenko
相关产品推荐
相关产品推荐

