SwiftUI中如何在显示加载指示器时禁用视图交互?
解决SwiftUI加载指示器显示时无法禁用用户交互的问题
你当前给Loading视图添加allowsHitTesting(false)的做法是错误的——这个修饰符会让加载视图不接收任何点击事件,点击会直接穿透到下层的按钮,所以按钮依然能被触发。正确的思路是让加载视图接收点击事件,从而拦截下层所有交互元素的点击。
具体修改步骤
- 给
Loading视图添加绑定变量,用来控制加载状态的显示/隐藏(实际应用中可根据API请求状态切换该值); - 移除
Loading及其子视图上的allowsHitTesting(false),让加载视图默认接收点击,实现拦截下层交互的效果; - 在
ContentView中添加状态变量,控制加载视图的显示逻辑。
修改后的完整代码
Loading视图代码
import SwiftUI struct Loading: View { @Binding var isShowing: Bool var body: some View { if isShowing { ZStack { BlurView() .allowsHitTesting(true) VStack { Indicator() } } .frame(maxWidth: .infinity, maxHeight: .infinity) .edgesIgnoringSafeArea(.all) } } } struct BlurView: UIViewRepresentable { func makeUIView(context: UIViewRepresentableContext<BlurView>) -> UIVisualEffectView { let effect = UIBlurEffect(style: .systemMaterial) let view = UIVisualEffectView(effect: effect) return view } func updateUIView(_ uiView: UIVisualEffectView, context: UIViewRepresentableContext<BlurView>) {} } struct Indicator: UIViewRepresentable { func makeUIView(context: UIViewRepresentableContext<Indicator>)-> UIActivityIndicatorView { let ind = UIActivityIndicatorView(style: .medium) ind.startAnimating() return ind } func updateUIView(_ uiView: UIActivityIndicatorView, context: Context) {} }
ContentView代码
import SwiftUI struct ContentView: View { @State private var isLoading = true // 实际开发中根据API请求状态切换该值 var body: some View { NavigationView { ZStack { VStack { Button { print("Button tapped") } label: { Text("Tap me") } .frame(width: 200, height: 60) .background(.red) Spacer() } Loading(isShowing: $isLoading) } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
效果说明
当isLoading为true时,加载视图会铺满整个屏幕并接收所有点击事件,下层按钮无法被触发;加载完成后将isLoading设为false,加载视图消失,按钮恢复可交互状态。
内容的提问来源于stack exchange,提问作者user10469417
相关产品推荐
相关产品推荐

