前言
紧接上一篇小组件的创建SwiftUI 小组件 Widget(一)
这篇来讲一下小组件的尺寸
小组件最开始支持小、中、大三个尺寸,分别是 systemSmall、systemMedium、systemLarge
到iOS 15 新增了超大号,用于iPad端的 systemExtraLarge
再到iOS 16 新增了锁屏小组件分别是accessoryCircular、accessoryRectangular、accessoryInline
机型 | systemSmall(pt) | systemMedium(pt) | systemLarge(pt) |
---|---|---|---|
se1 | 141 * 141 | 292 * 141 | 292 * 311 |
6s/7/8/se2/se3 | 148 * 148 | 321 * 148 | 321 * 324 |
x/xs/11pro/12mini/13mini | 155 * 155 | 329 * 155 | 329 * 345 |
12/12pro/13/13pro/14/14pro/15/15pro | 158 * 158 | 338 * 158 | 338 * 354 |
6sPlus/7Plus/8Plus | 159 * 159 | 348 * 157 | 348 * 357 |
xr/xsMax/11/11proMax | 169 * 169 | 360 * 169 | 360 * 379 |
12pm/13pm/14plus/14pm/15plus/15pm | 170 * 170 | 364 * 170 | 364 * 382 |
机型 | accessoryCircular(pt) | accessoryRectangular(pt) | accessoryInline(pt) |
---|---|---|---|
8/SE2/SE3 | 56 * 56 | 142 * 56 | 225 * 26 |
8P/XR/11/12PM/13PM/14P/ 14PM/15P/15PM | 60 * 60 | 154 * 60 | 248 * 26 |
X/XS/11Pro/12Min/12/12Pro/ 13Min/13/13Pro/14/14Pro/15/ 15Pro | 58 * 58 | 143 * 58 | 255 * 26 |
XS MAX | 54 * 54 | 156 * 64 | 248 * 26 |
11 Pro Max | 64 * 64 | 156 * 64 | 248 * 26 |
上面2个表是不同尺寸的小组件在不同屏幕上的大小,可供设计的同学参考。
在开发的过程中如果我们只需支持小、中2个尺寸,该怎么设置呢?有2种方法。
1、在Widget中选择多个支持尺寸
struct MyWidget: Widget {
let kind: String = "MyWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
MyWidgetEntryView(entry: entry)
}
///支持的小组件尺寸
.supportedFamilies([.systemSmall, .systemMedium])
.configurationDisplayName("My Widget")
.description("This is an example widget.")
}
}
那么如果我要支持锁屏小组件,但是我们的Target 又要适配iOS 14,该怎么办呢?
我们可以把小组件尺寸写成属性,然后判断版本号,给不同的数组
struct MyWidget: Widget {
let kind: String = "MyWidget"
private var supportedFamilies: [WidgetFamily] {
if #available(iOSApplicationExtension 16.0, *) {
return [
.systemSmall,
.systemMedium
.accessoryCircular,
.accessoryRectangular
]
} else {
return [
.systemSmall,
.systemMedium
]
}
}
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
MyWidgetEntryView(entry: entry)
}
///支持的小组件尺寸
.supportedFamilies(supportedFamilies)
.configurationDisplayName("My Widget")
.description("This is an example widget.")
}
}
这样在添加小组件的时候,就会在iOS16以下显示 小、中2个尺寸的小组件,在iOS 16以上显示 小中,以及圆形,矩形2个锁屏小组件的选择。
2、用WidgetBundle,创建多个Widget,每个Widget支持不同的尺寸
struct SmallWidget: Widget {
let kind: String = "SmallWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
SmallWidgetEntryView(entry: entry)
}
///支持的小组件尺寸
.supportedFamilies([.systemSmall])
.configurationDisplayName("SmallWidget")
.description("This is an example widget.")
}
}
struct MediumWidget: Widget {
let kind: String = "MediumWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
MediumWidgetEntryView(entry: entry)
}
///支持的小组件尺寸
.supportedFamilies([.systemMedium])
.configurationDisplayName("MediumWidget")
.description("This is an example widget.")
}
}
struct MyWidgetBundle: WidgetBundle {
var body: some Widget {
SmallWidget()
MediumWidget()
}
}
当然也可以每个Widget都支持多个尺寸,那样就不止显示2个小组件了,例如每个Widget都支持小中2个尺寸,那在添加小组件的时候显示的就是4个小组件了。
尺寸判断
要如何在不同的尺寸小组件上面渲染不同的UI呢,以上2个支持小组件的方法中,第二种方法因为是分开不同的Widget的,所以一个Widget代表一个尺寸,也就是根本不用判断当前Widget是啥尺寸,因为已经知道了。那第一种只有1个Widget的时候该怎么判断呢?
struct LearningWidgetEntryView : View {
/// 提供尺寸
@Environment(\.widgetFamily) var family
var entry: Provider.Entry
var body: some View {
switch family {
case .systemSmall:
SmallView()
case .systemMedium:
MediumView()
case .systemLarge:
LargeView()
case .systemExtraLarge:
ExtraLargeView()
case .accessoryCircular:
CircularView()
case .accessoryRectangular:
RectangularView()
case .accessoryInline:
InlineView()
@unknown default:
Text(entry.date, style: .time)
}
}
}
WidgetKit中提供了这么一个枚举 @Environment(\.widgetFamily) var family 来判断当前小组件的尺寸,通过判断渲染不同的View。
小组件尺寸介绍暂时告一段落,后面如果发现有啥漏的再来补上。