SwiftUI 小组件 Widget(二)

前言

紧接上一篇小组件的创建SwiftUI 小组件 Widget(一)

这篇来讲一下小组件的尺寸

小组件最开始支持小、中、大三个尺寸,分别是 systemSmallsystemMediumsystemLarge

iOS 15 新增了超大号,用于iPad端的 systemExtraLarge

再到iOS 16 新增了锁屏小组件分别是accessoryCircularaccessoryRectangularaccessoryInline

机型

systemSmall(pt)

systemMedium(pt)

systemLarge(pt)

se1141 * 141292 * 141292 * 311
6s/7/8/se2/se3148 * 148321 * 148321 * 324
x/xs/11pro/12mini/13mini155 * 155329 * 155329 * 345
12/12pro/13/13pro/14/14pro/15/15pro158 * 158338 * 158338 * 354
6sPlus/7Plus/8Plus159 * 159348 * 157348 * 357
xr/xsMax/11/11proMax169 * 169360 * 169360 * 379
12pm/13pm/14plus/14pm/15plus/15pm170 * 170364 * 170364 * 382
机型

accessoryCircular(pt)

accessoryRectangular(pt)

accessoryInline(pt)

8/SE2/SE356 * 56142 * 56225 * 26

8P/XR/11/12PM/13PM/14P/

14PM/15P/15PM

60 * 60154 * 60248 * 26

X/XS/11Pro/12Min/12/12Pro/

13Min/13/13Pro/14/14Pro/15/

15Pro

58 * 58143 * 58255 * 26
XS MAX54 * 54156 * 64248 * 26
11 Pro Max64 * 64156 * 64248 * 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。

小组件尺寸介绍暂时告一段落,后面如果发现有啥漏的再来补上。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值