前言
解决如何添加一个锁屏小组件的问题,其实很简单,就是在桌面小组件的基础上新增了3个WidgetFamily类型去支持锁屏小组件,我们只需要支持一下WidgetFamily和视图即可。
说明
iOS16 新增了锁屏的编辑功能,其中有两块区域可以放置小组件,WidgetFamily也新增了accessoryInline、accessoryRectangular、accessoryCircular三种。对应关系如下图所示:
一、accessoryInline
accessoryInline类型小组件只能放置在顶部的小组件区域,只能放置一行Image与Text且长度固定,左边一定会带有一个系统日期。
二、accessoryRectangular、accessoryCircular
accessoryRectangular和accessoryCircular 只能放在==下方的小组件区域(1x4)==排列组合。 accessoryRectangular外形是一个圆角矩形,内容是一个矩形,占位1x2所以最多放置2个。上下左右是有一定的边距的,并不是填满。 accessoryCircular外形是是一个圆角方形,内容是一个圆形,占位1x1所以最多放置4个。上下左右是有一定的边距的,并不是填满。
限制
- 刷新机制依旧延续桌面小组件的刷新机制。
- 文字和图片的颜色设置无效,在锁屏小组件上都会被渲染成系统时间一样的颜色,但是颜色设置会导致颜色的深浅不一样。
- accessoryInline 只能显示Image 与Text ,accessoryRectangular、accessoryCircular 还能显示一些ProgressView 。
- 尺寸非常小,且位置固定,展示内容有限。
- 无法像桌面小组件一样长按打开后面的编辑页面用SiriIntent 提供用户配置,自由度较小。
代码
只需要在Widget入口的supportedFamilies属性中支持即可
@main
struct MyWidget: Widget {
let kind: String = "MyTWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
WidgetEntryView(entry: entry)
}
.configurationDisplayName("xxx")
.description("xxx")
.supportedFamilies([.accessoryInline, .accessoryRectangular, .accessoryCircular])
}
}
视图则可以使用 @Environment(.widgetFamily) var family 来区分尺寸,编写不同的视图。
struct WidgetEntryView : View {
var entry: Provider.Entry
@Environment(\.widgetFamily) var family
var body: some View {
switch family{
case .accessoryInline :
Text("顶部文字")
case .accessoryCircular :
Text("1x1组件")
case .accessoryRectangular :
Text("1x2组件")
default :
Text("默认")
}
}
}
如果你的项目目标系统是iOS14,Widget还要支持iOS14 的桌面小组件,可以使用版本判断来区分supportedFamilies
func getWidgetSupportedFamilies () -> [WidgetFamily]{
if #available(iOS 16, *) {
return [.accessoryInline, .accessoryRectangular, .accessoryCircular, .systemSmall]
} else {
return [.systemSmall]
}
}
@main
struct MyWidget: Widget {
let kind: String = "MyTWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
WidgetEntryView(entry: entry)
}
.configurationDisplayName("xxx")
.description("xxx")
.supportedFamilies(getWidgetSupportedFamilies())
}
}
如果需要像闹钟那样的毛玻璃背景的话可以使用 AccessoryWidgetBackground()
struct WidgetEntryView : View {
var entry: Provider.Entry
@Environment(\.widgetFamily) var family
var body: some View {
switch family{
case .accessoryInline :
Text("顶部文字")
case .accessoryCircular :
ZStack {
AccessoryWidgetBackground()
Text("1x1组件")
}
case .accessoryRectangular :
Text("1x2组件")
default :
Text("默认")
}
}
}
参考文献
本人新手,如果有写错的地方欢迎指正,期待和大家一起交流开发。
《Apple-creating-a-widget-extension》 《Apple-widgetfamily》 《Apple-Creating Lock Screen Widgets and Watch Complications》 《iOS14 Widget开发踩坑(一)修正版-初识别与刷新》 《iOS14WidgetKit开发实战1-4》
|