You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:07:37