SwiftUI实现点击弹窗外部或键盘弹出时关闭自定义popup modal
实现方案
要实现你需要的两个交互逻辑,只需要新增蒙层点击监听+系统通知监听两步即可,修改后的完整代码如下:
import SwiftUI struct HelpView: View { @State var text = "" @State var thingIsDisplayed = false var body: some View { ZStack { VStack { Button(action: { withAnimation { thingIsDisplayed.toggle() } }) { Text("Toggle Thing") } TextField("Something", text: $text) Spacer() } .padding() // 新增:弹窗显示时的全屏透明蒙层,监听外部点击 if thingIsDisplayed { Color.clear .ignoresSafeArea() .onTapGesture { withAnimation { thingIsDisplayed = false } } } VStack { Spacer() if thingIsDisplayed { // 这里的Rectangle是你的自定义弹窗内容示例 Rectangle() .frame(height: 300) // 弹窗自身的交互逻辑可以在这里添加,不会触发外部关闭逻辑 } } .transition(AnyTransition.move(edge: .bottom)) } // 新增:监听键盘弹出通知,自动关闭弹窗 .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { _ in guard thingIsDisplayed else { return } withAnimation { thingIsDisplayed = false } } } } struct HelpView_Previews: PreviewProvider { static var previews: some View { HelpView() } }
关键修改说明
- 点击外部关闭逻辑:
- 弹窗显示时会先渲染一层全屏透明的
Color作为蒙层,蒙层位于弹窗内容的下层,只会拦截弹窗以外的点击事件,点击后执行关闭逻辑,不会影响弹窗本身的交互。
- 弹窗显示时会先渲染一层全屏透明的
- 键盘唤起自动关闭逻辑:
- 通过
onReceive监听系统UIResponder.keyboardWillShowNotification通知,只要键盘即将弹出就会自动触发弹窗关闭,和原有的弹窗动画保持一致。
- 通过
如果需要在多个页面复用该弹窗逻辑,也可以把蒙层和监听逻辑封装成单独的ViewModifier即可。
内容的提问来源于stack exchange,提问作者emehex
相关产品推荐
相关产品推荐

