iOS开发之构建Widget

挑战接受!话说最近围绕着Widget的话题可真是热热闹闹啊!相信各位腕上功夫高超的大佬们已经津津有味的把Widget搞起来,有没有搞得挺过瘾的感觉?那对于还在Widget上懵懵懂懂的小白们来说,不要慌,我来给你带来一场Widget的构建之旅~

Widget这个东西,在iOS14上被苹果官方推出来了,也就是说,新的Widget视图可以显示在用户的主屏幕上了,丰富了iOS系统的形态。以前呢,我们只有在通知中心中看到过Widget,iOS14中的Widget可以显示在桌面上了,但是有一个限制——最多只能放置10个同类型(大小不同,大的和小的算两个)的Widget。不过,这完全不影响我们嗨皮构建Widget呀!

首先呢,我们得创建一个Widget Extension目标。步骤如下:

- 打开Xcode,然后选择File -> New -> Target。

- 在展开的菜单中,找到Application Extension,然后点击下面的Widget Extension。

- 按下Next,输入Product Name ,可选择相关的 Group,再按Create,此时Xcode会自动生成 Widget Extension 代码结构。

除此之外,我们还需要对Widget中的View进行设置,比如widgetFamily、body、等等。代码举例:

```swift

struct MyAppWidgetView: View {

var body: some View {

VStack {

Text("这里是Widget的标题")

Image(systemName: "cloud.sun.rain.fill")

.font(.system(size: 50))

Text("这里是Widget的内容")

}

.padding(EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10))

}

}

@main

struct MyAppWidget: Widget {

let kind: String = "MyAppWidget"

var body: some WidgetConfiguration {

StaticConfiguration(kind: kind, provider: MyProvider()) { entry in

MyAppWidgetView()

}

.configurationDisplayName("小I")

.description("这是一个自定义小组件") }

}

struct MyEntry: TimelineEntry {

let date: Date

let relevance: TimelineEntryRelevance?

let name: String

}

struct MyProvider: TimelineProvider {

func placeholder(in context: Context) -> MyEntry {

MyEntry(date: Date(), relevance: nil, name: "占位")

}

func getSnapshot(in context: Context, completion: @escaping (MyEntry) -> ()) {

let entry = MyEntry(date: Date(), relevance: nil, name: "快照")

completion(entry)

}

func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) {

let entry = MyEntry(date: Date(), relevance: nil, name: "刻度")

let timeline = Timeline(entries: [entry], policy: .atEnd)

completion(timeline)

}

}

```

上面这段代码主要功能就是构建一个简单的Widget,你可以根据自己的需求进行修改。其中:

- MyAppWidgetView:是Widget中的View,用来展示widget的样式,响应事件,可视为一个自定义的小组件。

- MyProvider:插件提供程序,用于提供有关小组件的信息,比如占位符,快照和时间轴数据。

Widget中有几个属性值,我们可以自己设置,分别如下:

- var widgetFamily: @WidgetFamily :当前的Widget的类型,目前有三种:systemSmall、systemMedium、systemLarge,分别表示简约型、中等型、详细型。

- var body: Body :主要内容,是一个AnyView类型的值,这意味着你可以返回任何的类型作为主要内容,包括文字、图片、按钮等等。

而且,除此之外,我们还可以把小组件设置成动态类型的Widget。动态类型的Widget意味着视图在不同的状态下会呈现不同的内容。所以我们还需要 TimelineProvider 和 TimelineEntry。

TimelineProvider:提供时间轴支持来展示动态Widget的更新数据的可演变过程,主要功能是获取用于更新小组件的数据。

TimelineEntry:构建数据源模型的内容,它有三个参数:

- date:时间datetime类型的,表示数据的生成时间;

- relevance:数据时效性相关,和date一起使用;

- content:小组件的内容,参数可以是任何小组件。

呼~~~深呼吸,是不是有点看不懂了?别着急,我们还是直接看一下代码:

```swift

struct MyAppWidgetView: View {

var text: String

var body: some View {

Text(text)

}

}

@main

struct MyAppWidget: Widget {

let kind: String = "MyAppWidget"

var body: some WidgetConfiguration {

StaticConfiguration(kind: kind, provider: MyProvider()) { entry in

MyAppWidgetView(text: entry.text)

}

.configurationDisplayName("小I")

.description("这是一个自定义小组件")

}

}

//TimelineProvider适用于具有周期更新行为的Widget

struct MyProvider: TimelineProvider {

//定义一个返回PlaceholderEntry类型元素的函数

func placeholder(in context: Context) -> MyEntry {

MyEntry(date: Date(), relevance: nil, text: "占位")

}

//.systemSmall为Static Configuration下的子配置项

func getSnapshot(in context: Context, completion: @escaping (MyEntry) -> ()) {

let entry = MyEntry(date: Date(), relevance: nil, text: "快照")

completion(entry)

}

//根据传递的参数,在构建初始视图之后获取一组一次性数据,主要用于更新Widget的初始状态

func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) {

var entries = [MyEntry]()

// Generate a timeline consisting of five entries an hour apart, starting from the current date.

let currentDate = Date()

for hourOffset in 0 ..< 5 {

let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!

let entry = MyEntry(date: entryDate, relevance: nil, text: "\(hourOffset) 小时前的数据")

entries.append(entry)

}

let timeline = Timeline(entries: entries, policy: .atEnd)

completion(timeline)

}

}

struct MyEntry: TimelineEntry {

let date: Date

let relevance: TimelineEntryRelevance?

let text: String

}

```

其中:

- MyAppWidgetView:展示Widget中的内容,这里我们把展示的内容设置成TextView。

- MyProvider:数据提供者,在初始化,快照视图和时间轴更新中生成Widget的初始状态。

- TimelineProvider、TimelineEntry:此处涉及到了数据的更新,在getTimeline() 方法中每小时更新一次数据,共更新五次。而MyEntry则是每次更新所包含的数据内容,这里我们只包含一个text属性。

好了,到这里,我们就介绍完了包含构建静态Widget和动态Widget的全部内容。如果你还不理解或者有疑问,可以再看看代码或者私信我哦~(BuildContext) www.0574web.net 宁波海美seo网络优化公司 是网页设计制作,网站优化,企业关键词排名,网络营销知识和开发爱好者的一站式目的地,提供丰富的信息、资源和工具来帮助用户创建令人惊叹的实用网站。 该平台致力于提供实用、相关和最新的内容,这使其成为初学者和经验丰富的专业人士的宝贵资源。

点赞(116) 打赏

声明本文内容来自网络,若涉及侵权,请联系我们删除! 投稿需知:请以word形式发送至邮箱18067275213@163.com

评论列表 共有 2 条评论

外用无敌膏 1年前 回复TA

貌似在防晒………

鞍山大象网 1年前 回复TA

我的网站也是这样,已经不存在的网页还存在google的收录中,但全部都标为补充材料,想着google什么时候可以把它们全都去掉多好,碍眼.

立即
投稿
发表
评论
返回
顶部