Widget Extension

1. Widget Extension理论知识

1.1  widget是一个独立的target,需要一套完整的证书 描述文件等

1.2 widget与主程序的信息交互,一方面:AppGroups   一方面:可尝试通过服务端

1.3 widget支持的展示,iPhone负一屏,桌面,锁屏,三个地方进行添加。另:锁屏与其他两处有所不同。

1.4 widget支持系统,自iOS 14+起,到iOS 16+可在锁屏添加,再到iOS 17+可直接通过小组件进行交互而不跳转主程序

2. Widget Extension具体实现, 基于iOS 17+

2.1 创建一个基础的Widget Extension

2.1.1 xCode打开项目,File -> New -> target -> Widget Extension

2.1.2 弹出的窗口栏,不要勾选 include Configuration App Intent 与 include Live Activity

2.1.3 run your widget

3. Widget Extension代码结构

一个基础的widget组成部分:输出Widgetbundle,结构体Widget,时间线TimelineProvider, 数据TimelineEntry,视图View

3.1  输出Widgetbundle, 输出结构体Widget

3.2 结构体Widget,  整合TimelineProvider, TimelineEntry, View

3.3  时间线TimelineProvider,widget的刷新机制

3.4  数据TimelineEntry,存储信息的结构体

3.4 视图View,展示的UI

import SwiftUI
import WidgetKit

// 输出WidgetBundle
@main
struct TestWidgetBundle: WidgetBundle {
    var body: some Widget {
        //这里输出widget实体
        TestWidget()
    }
}

//结构体Widget
struct TestWidget: Widget {
    let kind: String = "widget.com"

    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { entry in

            //这里放widget视图
            if #available(iOS 17.0, *) {
                TestWidgetView(entry: entry)
                    .containerBackground(.fill.tertiary, for: .widget)
            } else {
                TestWidgetView(entry: entry)
                    .padding()
                    .background()
            }
        }
        .configurationDisplayName("widget")
        .description("This is an widget")
        .supportedFamilies([.systemSmall,.systemMedium,.systemLarge,.accessoryInline,.accessoryCircular,.accessoryRectangular]) //支持的样式,后三种iOS 16+
    }
}

//时间线TimelineProvider
struct Provider: TimelineProvider {
    
    typealias Entry = SimpleEntry

    //等待数据加载,占位视图
    func placeholder(in context: Context) -> Entry {
        Entry(date: Date())
    }
    //小组件库中,展示用的视图,可以理解为商品橱窗里面的展示品
    func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) {
        completion(Entry(date: Date()))
    }

    //加载成功,真正用于交互展示的视图
    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
        let entry = Entry(date: Date())
        let timeline = Timeline(entries: [entry], policy: .never)
        completion(timeline)
    }
}

//数据TimelineEntry
struct SimpleEntry: TimelineEntry {
    let date: Date
    //... 其余数据
}


//视图View
struct TestWidgetView : View {
    var entry: Provider.Entry

    var body: some View {
        VStack {
            HStack {
                Text("widget:")
                Text(entry.date, style: .time)
            }
            HStack {
                Text("press me 1").padding(5).background(Color.teal)
                Text("press me 2").padding(5).background(Color.teal)
                Text("press me 3").padding(5).background(Color.teal)
            }
            .padding(.vertical, 20)
        }
    }
}

上面代码,直接复制进widget target看看小组件是否能跑起来

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值