美文网首页
iOS中Widget的构建

iOS中Widget的构建

作者: MambaYong | 来源:发表于2023-05-04 15:10 被阅读0次

什么是widget

iOS Widget是一种可以放置在 iOS 设备主屏幕上的小型应用程序,提供了一个快速访问和浏览信息的方式。 Widget可以显示各种类型的内容,例如天气、日历、媒体播放器、时钟等等。

iOS Widget 的最大特点是可以在主屏幕上快速查看并与应用程序进行交互,而无需打开应用程序。 Widget 需要使用 WidgetKit 框架来创建和管理,WidgetKit提供了各种各样的组件和 API,使得开发者可以在 Widget中实现丰富的功能和交互体验。

本文要实现的Demo效果如下图所示,显示的是当前时间的Widget

新建widget

首先直接新建一个target,因为widget实际上就是一个target,所显示的数据是依赖宿主App的,创建完widgetxcode会帮我们新建好示例代码。

示例代码中有几个类了解才能知道如何正确构建widget

TimelineEntry

这个类是用来给widget提供数据的,我们可以简单理解为提供数据的demo,唯一的要求是必须要有一个表示时间的属性var date: Date { get },这个属性的作用我们稍后解释,定义一个TimelineEntry结构体如下:

struct SimpleEntry: TimelineEntry {
    let date: Date
    var hour : Int {
        Calendar.current.component(.hour, from: self.date)
    }
    var minute: Int {
        Calendar.current.component(.minute, from: self.date)
    }
}

其中hourminute变量用来显示当前时间的小时和分钟。

TimelineProvider

这是一个协议,还是看一段官方的解释:

A type that advises WidgetKit when to update a widget's display.At various times, WidgetKit requests a timeline from the provider. A timeline is an array of objects conforming to <doc:TimelineEntry>. Eachtimeline entry has a date, and you can specify additional propertiesfor displaying the widget.

这个协议告诉WidgetKit什么时候更新widget,就是给WidgetKit提供数据源,数据源就是上面的TimelineEntry实体,当然还包括更新策略也就是在什么时间需要更新,协议里面有几个方法需要实现:

  func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date())
    }

这个方法是提供一个站位视图,因为我们为WidgetKit提供的数据有可能是异步请求的,这时如果添加widget时,数据可能还没准备好,此时我们可以提供一个站位视图,让用户知道大概得widget样子,这里简单的用当前时间初始化了SimpleEntry

    func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date())
        completion(entry)
    }

这个方法是提供静态快照,当我们添加widget时我们需要在widget gallery中提供一个快照。

    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
        var entries: [SimpleEntry] = []
        let date = Date().zeroSeconds!
        for hourOffset in 0 ..< 60 {
            let entryDate = Calendar.current.date(byAdding: .minute , value: hourOffset, to: date)!
            let entry = SimpleEntry(date: entryDate)
            entries.append(entry)
        }
        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }

这个方法是提供一组数据用于显示,这里我们提供了基于当前时间的60组数据,每个entry数据的date间隔一分钟,并放入了一个entries数组里面,并告知了刷新策略是.atEnd,也就是在60组数据显示完后再更新,此时又会基于当前时间提供60组数据,每个entry数据的date值间隔一分钟,循环如此。

可以发现getSnapshotgetTimeline都利用逃逸闭包来提供entry,这表明方法里面可以进行异步的操作,例如可以进行网络请求,在网络请求成功后构建entry在利用闭包返回,而placeholder则没有提供逃逸闭包,所以这里尽量提供简单的数据。

构建view

利用上面的几个类组合起来构建view


struct widgetTimeEntryView : View {
    var entry: Provider.Entry
    var body: some View {
            VStack {
                HStack {
                 Text("时:   " + String(entry.hour))
                        .font(Font.system(size: 30))
                        .foregroundColor(Color.blue)
                        .background(Color.gray)
                 Spacer()
            }
                HStack {
                 Spacer()
                 Text("分:" + String(entry.minute))
                        .font(Font.system(size: 30))
                        .foregroundColor(Color.orange)
                        .background(Color.gray)
            }
                Text(entry.date, style: .timer)
        
        }
            .padding()
    }
}

@main
struct widgetTime: Widget {
    let kind: String = "widgetTime"

    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { entry in
            widgetTimeEntryView(entry: entry)
        }
        .configurationDisplayName("WidgetDemo")
        .description("This is an example widget.")
    }
}

view利用provider提供的entry来显示,下面的kind是唯一标识符,WidgetKitkind来管理widgetStaticConfiguration是一个配置类,这里需要传入kindprovider,在闭包中需要返回entryViewconfigurationDisplayNamedescription是当我们添加时widget显示的名字和描述信息。

总结

本文简单的介绍了iOSwidget的构建,当然widget和宿主之间是可以进行通信的,比如共享数据同时widget也可以和用户完成交互后,利用用户的交互信息在更新状态,widget的使用主要需要明白entery的构建和其中通过provider如何进行流转的。

相关文章

  • Flutter Widget之初体验 for iOSer

    Widget(小部件)定义: 在 iOS 中,构建 UI 的过程中将大量使用 view 对象。这些对象都是 UIV...

  • Widgets 介绍

    Flutter Widget采用现代响应式框架构建,这是从 React 中获得的灵感,中心思想是用widget构建...

  • iOS之构建Widget

    伴随这iOS 8 系统多达4000项API更新而来同样还有Today Extension.而对iOS而言,有了To...

  • SwiftUI-Widget 使用及避坑指南

    iOS Widget简单介绍( 只介绍iOS 14 以后Widget相关内容): Widget 是 iOS 14 ...

  • 1. Flutter Widget

    定义:Widget是Flutter中构建UI的组件。 widget的两种状态 无状态的StatelessWidge...

  • Flutter 学习 - Widget 之 Text

    前言 什么是Widget Widget是学习Flutter的基础,用于构建UI,相当于Android中的View,...

  • iOS开发之构建Widget

    伴随这iOS 8 系统多达4000项API更新而来同样还有Today Extension.而对iOS而言,有了To...

  • IOS Widget 开发笔录

    IOS widget开发笔录 刚完成IOS widget开发,仿照UC头条,头条日报widget,附上效果图: 目...

  • Flutter widget框架

    Flutter Widget 采用现代响应式框架构建,这是从 React 中获得的灵感,中心思想是用 Widget...

  • 2. Flutter 之 Widget(生命周期)

      Widget其实就是Flutter的组件、控件,在Flutter中万物皆Widget;在我们iOS或者Andr...

网友评论

      本文标题:iOS中Widget的构建

      本文链接:https://www.haomeiwen.com/subject/ydlugrtx.html