如何在watchOS的SwiftUI中创建带图标的类Alert自定义视图?
实现带图标的类原生WatchOS Alert视图
要实现兼具原生Alert的全屏覆盖、模糊背景特性,同时支持顶部图标+标题的自定义Alert,你可以通过以下方式修改代码:
核心解决方案
利用fullScreenCover结合模糊背景层,同时通过安全区域配置避免内容与时钟重叠,还原原生Alert的布局逻辑:
struct CustomAlertView: View { @EnvironmentObject var dataProvider: DataProvider @Binding var isPresented: Bool // 添加绑定用于关闭Alert var alert: Watch.AlertMessage var body: some View { ZStack { // 模拟原生Alert的模糊背景 Color.black.opacity(0.5) .ignoresSafeArea(edges: .all) .background(.ultraThinMaterial) // 内容容器,限制宽度并居中,避免拉伸过满 VStack(spacing: 16) { ScrollView { VStack(spacing: 12) { // 顶部图标 Image("IconAlert") .resizable() .renderingMode(.template) .aspectRatio(contentMode: .fit) .frame(width: 40, height: 40) .foregroundColor(.accentColor) // 标题 Text(alert.title) .font(.headline) .bold() .multilineTextAlignment(.center) // 描述文本 Text(alert.description) .font(.body) .multilineTextAlignment(.center) } .padding() } .frame(maxWidth: .infinity) .background(Color.white) // 内容背景,和原生Alert一致 .cornerRadius(12) .padding(.horizontal, 16) // 底部关闭按钮,固定在底部 Button(action: { isPresented = false }) { Text("DISMISS") .font(.headline) .foregroundColor(.accentColor) .padding(.vertical, 12) .frame(maxWidth: .infinity) } .padding(.horizontal, 16) .padding(.bottom, 8) } .ignoresSafeArea(edges: .horizontal) // 水平方向忽略安全区,垂直方向保留避免和时钟重叠 } .navigationBarHidden(true) } }
关键优化点说明
- 模糊背景实现:通过
Color.black.opacity(0.5)叠加.background(.ultraThinMaterial),还原原生Alert的半透明模糊效果,且通过.ignoresSafeArea(edges: .all)覆盖包括状态栏在内的所有区域。 - 内容安全区域控制:垂直方向保留安全区,避免ScrollView滚动时内容与顶部时钟重叠;水平方向忽略安全区,让内容容器贴合屏幕两侧。
- 布局还原:将按钮固定在底部,内容区域居中并添加圆角,和原生Alert的视觉结构一致。
- 关闭逻辑:通过
@Binding var isPresented绑定外部的展示状态,点击按钮时关闭Alert。
使用方式
在父视图中调用:
struct ParentView: View { @State private var showAlert = false @EnvironmentObject var dataProvider: DataProvider var body: some View { Button("Show Alert") { showAlert = true } .fullScreenCover(isPresented: $showAlert) { CustomAlertView(isPresented: $showAlert, alert: Watch.AlertMessage(title: "Test Title", description: "Test Description")) } } }
这样实现的视图既保留了原生Alert的全屏覆盖、模糊背景特性,又支持自定义顶部图标,同时避免了内容与时钟重叠的问题。
内容的提问来源于stack exchange,提问作者Dustin
相关产品推荐
相关产品推荐

