SwiftUI单视图添加两个Alert仅第二个显示,如何让两个Alert均正常工作?
问题原因
核心是你将第二个Alert绑定到了包含Button的外层VStack上,SwiftUI中父视图的Alert优先级高于所有子视图的Alert,会直接覆盖子视图的Alert配置,因此哪怕两个Alert绑定到了不同视图,只要存在包含关系,依然只有父层级的Alert可以正常触发。
解决方案
方案1:调整绑定位置(兼容iOS13/14)
把第二个Alert绑定到和Button所在视图平级的独立透明视图上,避开父子视图的覆盖关系,修改后代码如下:
var body: some View { ScrollView { VStack (alignment: .leading) { // ...some stuff VStack { Button(action: { // dosomestuff showingIntrestedAlert.toggle() }) { Text("Press Me") }.alert(isPresented: $showingIntrestedAlert) { Alert(title: Text("alert1"), message: Text("showing alert 1"), dismissButton: .default(Text("OK"))) } } // 新增透明占位视图绑定第二个Alert,与上方视图平级无包含关系 Color.clear .frame(width: 0, height: 0) .alert(isPresented: $fromViewModel.alreadyLikedUser) { Alert(title: Text("alert2"), message: Text("alert 2 shown"), dismissButton: .default(Text("OK"))) } } } }
方案2:使用alert(item:)统一管理(推荐,iOS15+)
alert(isPresented:)从iOS15开始已经被官方标记为弃用,更推荐用枚举标识不同Alert、统一用alert(item:)管理的方式,无需绑定到不同视图,不会出现覆盖问题,维护性更强:
- 首先定义Alert类型枚举
enum ActiveAlert: Identifiable { case alert1, alert2 var id: Self { self } }
- 替换视图中的Alert触发逻辑
// 替换原来的两个Bool状态,新增状态变量 @State private var activeAlert: ActiveAlert? var body: some View { ScrollView { VStack (alignment: .leading) { // ...some stuff VStack { Button(action: { // dosomestuff activeAlert = .alert1 }) { Text("Press Me") } } } } // 统一配置Alert .alert(item: $activeAlert) { alertType in switch alertType { case .alert1: return Alert(title: Text("alert1"), message: Text("showing alert 1"), dismissButton: .default(Text("OK"))) case .alert2: return Alert(title: Text("alert2"), message: Text("alert 2 shown"), dismissButton: .default(Text("OK"))) } } // 监听ViewModel的状态变化触发alert2 .onChange(of: fromViewModel.alreadyLikedUser) { isLiked in if isLiked { activeAlert = .alert2 // 重置ViewModel状态避免重复触发 fromViewModel.alreadyLikedUser = false } } }
内容的提问来源于stack exchange,提问作者Gurmukh Singh
相关产品推荐
相关产品推荐

