如何让Bottom Sheet在TabView后方显示?仿DQ应用效果问询
实现DQ风格的Bottom Sheet(从TabView后方弹出)
默认SwiftUI的.sheet是模态弹窗,会显示在所有视图层级最上层,因此会覆盖TabView。要实现从TabView后方弹出的效果,需要自定义底部弹出视图,通过ZStack调整层级关系:
实现步骤
- 抛弃系统自带的
.sheet,改用自定义视图实现弹出逻辑 - 用ZStack将TabView放在上层,自定义Bottom Sheet放在下层
- 通过动画控制自定义视图的显示/隐藏,模拟弹出效果
修改后的代码
import SwiftUI struct Menu: View { @State private var showingBottomSheet = true // 控制底部视图偏移量,实现弹出动画 @State private var bottomSheetOffset: CGFloat = UIScreen.main.bounds.height var body: some View { ZStack(alignment: .bottom) { // 自定义Bottom Sheet,放在ZStack底层 Color.white .frame(height: 300) .offset(y: bottomSheetOffset) .overlay(Text("hello")) // TabView放在上层,背景设为透明,避免遮挡底层视图 TabView{ orderView() .tabItem{ Image(systemName: "questionmark") Text("Order") } rewardView() .tabItem{ Image(systemName: "star") Text("Rewards") } dealsView() .tabItem{ Image(systemName: "tag") Text("Deals") } myDQView() .tabItem{ Image(systemName: "person") Text("My DQ") } currentOrderView() .tabItem{ Image(systemName: "bag") } } .background(Color.clear) // 关键:让TabView背景透明,露出底层Bottom Sheet .onAppear { // 页面加载时触发弹出动画 if showingBottomSheet { withAnimation(.easeOut(duration: 0.3)) { bottomSheetOffset = 0 } } } } .edgesIgnoringSafeArea(.bottom) // 忽略底部安全区,让Bottom Sheet贴底 } } // 示例子视图,实际项目替换为你的真实视图 struct orderView: View { var body: some View { Text("Order View") } } struct rewardView: View { var body: some View { Text("Reward View") } } struct dealsView: View { var body: some View { Text("Deals View") } } struct myDQView: View { var body: some View { Text("My DQ View") } } struct currentOrderView: View { var body: some View { Text("Current Order View") } } struct Menu_Previews: PreviewProvider { static var previews: some View { Menu() } }
关键说明
- 层级控制:ZStack中TabView在上层,自定义Bottom Sheet在下层,通过
background(Color.clear)让TabView不遮挡底层视图 - 动画实现:利用
offset属性控制Bottom Sheet位置,配合withAnimation实现平滑的弹出/收起效果 - 安全区处理:
edgesIgnoringSafeArea(.bottom)让Bottom Sheet贴合屏幕底部,和DQ应用效果一致
内容的提问来源于stack exchange,提问作者k.arias
相关产品推荐
相关产品推荐

