SwiftUI:如何在Bottom Sheet上叠加显示视图?
实现Bottom Sheet上方叠加LoadingView的方案
核心思路
用状态变量控制LoadingView的显隐,通过ZStack把LoadingView叠在Bottom Sheet内容的上层,同时添加半透明遮罩防止用户误触底层内容。
完整代码示例
struct ContentView: View { // 控制Bottom Sheet弹出的状态 @State private var showBottomSheet = false // 控制LoadingView显示的状态 @State private var isLoading = false var body: some View { Button("弹出Bottom Sheet") { showBottomSheet = true } .sheet(isPresented: $showBottomSheet) { BottomSheetContent(isLoading: $isLoading) } } } struct BottomSheetContent: View { @Binding var isLoading: Bool // 处理Add按钮点击逻辑 func handleAddTap() { isLoading = true // 替换成你的实际业务逻辑,比如网络请求 DispatchQueue.main.asyncAfter(deadline: .now() + 2) { isLoading = false // 请求完成后的操作,比如关闭Bottom Sheet } } var body: some View { ZStack { VStack(spacing: 20) { // Bottom Sheet的其他内容 Text("Bottom Sheet内容") // 你的Add按钮(调整了高度,避免点击区域过小) Button(action: handleAddTap) { Text("Add") .padding(.horizontal, 5) .fontWeight(.semibold) .font(.custom("CashMarket-Medium", size: 17)) .frame(width: 300, height: 40, alignment: .center) } .buttonStyle(AddCashbutton()) } // 叠加的LoadingView if isLoading { // 半透明遮罩,阻止底层交互 Color.black.opacity(0.5) .ignoresSafeArea() .onTapGesture {} // 加载提示组件 VStack { ProgressView() .tint(.white) .scaleEffect(1.5) Text("加载中...") .foregroundColor(.white) .padding(.top, 8) } .padding(20) .background(Color.gray.opacity(0.8)) .cornerRadius(12) } } .padding() } } // 你的自定义ButtonStyle struct AddCashbutton: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .background(configuration.isPressed ? Color.blue.opacity(0.8) : Color.blue) .foregroundColor(.white) .cornerRadius(8) } }
关键注意点
- 状态同步:用
@Binding传递isLoading状态,确保父视图和Bottom Sheet的状态一致。 - 按钮高度:原代码里按钮
height:10会导致可点击区域极小,建议改成合适高度(比如40),避免点击无响应。 - 交互阻断:半透明遮罩加上空的
onTapGesture,可以防止用户在加载时点击Bottom Sheet的其他内容。
内容的提问来源于stack exchange,提问作者DevExodus
相关产品推荐
相关产品推荐

