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

如何在Swift应用内的自定义视图中添加Widget组件?

在App内嵌入Widget视图的实现方案

1. 复用Widget的核心视图组件

首先要让主App能访问Widget Extension里的视图代码:

  • 在Widget Extension的文件中,把你的Widget主视图(比如MyWidgetView)和对应的Entry结构体标记为public,确保主App可以调用:
// Widget Extension 中的代码
public struct SimpleEntry: TimelineEntry {
    public let date: Date
    public let someData: String // 你自定义的业务数据
    
    public init(date: Date, someData: String) {
        self.date = date
        self.someData = someData
    }
}

public struct MyWidgetView: View {
    public let entry: SimpleEntry
    
    public var body: some View {
        // 保留你原来的Widget布局代码
        VStack(spacing: 8) {
            Text("当前时间")
                .font(.headline)
            Text(entry.date, style: .time)
                .font(.title)
            Text(entry.someData)
                .font(.caption)
        }
        .padding()
        .background(Color.gray.opacity(0.1))
    }
    
    public init(entry: SimpleEntry) {
        self.entry = entry
    }
}
  • 给主App添加Widget Extension依赖:打开Xcode,选中主App的Target → 进入Build Phases → 在Target Dependencies中添加你的Widget Extension。

2. 在App内创建Widget展示容器

在主App里新建一个视图,模拟Widget的运行环境,构造Entry数据并复用Widget视图:

// 主App内的Widget展示视图
struct InAppWidgetContainer: View {
    // 从App内的数据源获取真实数据,这里先用模拟数据示例
    private let mockEntry = SimpleEntry(date: Date(), someData: "App内专属Widget内容")
    
    var body: some View {
        MyWidgetView(entry: mockEntry)
            // 模拟系统中等尺寸Widget的大小,可根据需求调整
            .frame(width: 320, height: 150)
            // 模仿系统Widget的圆角和阴影样式
            .clipShape(RoundedRectangle(cornerRadius: 16))
            .shadow(color: .black.opacity(0.1), radius: 4, x: 0, y: 2)
    }
}

之后你就可以像使用普通SwiftUI视图一样,把InAppWidgetContainer放到任何你需要的页面中,比如:

struct HomeView: View {
    var body: some View {
        VStack(spacing: 20) {
            Text("我的应用")
                .font(.largeTitle)
            // 嵌入Widget视图
            InAppWidgetContainer()
            Spacer()
        }
        .padding()
    }
}

3. 适配多尺寸Widget(可选)

如果你的Widget支持小、中、大三种尺寸,可以通过枚举来控制容器的尺寸:

struct InAppWidgetContainer: View {
    enum WidgetSize {
        case small, medium, large
    }
    
    let size: WidgetSize
    private let mockEntry = SimpleEntry(date: Date(), someData: "多尺寸适配Widget")
    
    var body: some View {
        MyWidgetView(entry: mockEntry)
            .frame(
                width: size == .small ? 155 : size == .medium ? 320 : 320,
                height: size == .small ? 155 : size == .medium ? 150 : 320
            )
            .clipShape(RoundedRectangle(cornerRadius: 16))
            .shadow(color: .black.opacity(0.1), radius: 4, x: 0, y: 2)
    }
}

// 使用时指定尺寸
InAppWidgetContainer(size: .large)

4. 处理Widget交互(可选)

如果Widget原本有点击跳转逻辑,在App内可以直接用onTapGesture替换或补充:

MyWidgetView(entry: mockEntry)
    .onTapGesture {
        // 这里添加App内的跳转逻辑,比如导航到详情页
        print("App内Widget被点击")
    }

内容的提问来源于stack exchange,提问作者Togosling

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 22:07:48