如何移除Swift WidgetBundle的@available标签,兼容iOS14/15主屏组件?
问题
我在WidgetBundle中编写了如下代码,但希望移除@available标签——当前写法下iOS16以下的用户无法访问主屏或锁屏组件:
struct WidgetBundler: WidgetBundle { @WidgetBundleBuilder var body: some Widget { HomeScreenWidget() LockScreenWidget() } }
编译器不接受这段代码,我自己想到了一个替代方案,但想寻求更优的写法,确保iOS14、15用户也能正常访问主屏组件:
struct WidgetBundler: WidgetBundle { @WidgetBundleBuilder var body: some Widget { if #available(iOSApplicationExtension 16, *) { HomeScreenWidget() LockScreenWidget() } else { HomeScreenWidget() } } }
请问有没有更优的方式移除@available标签,同时保证iOS14和15用户能访问主屏组件?
解决方案
你可以通过两种更简洁的方式实现需求,避免冗余的分支判断:
方式一:给锁屏组件单独标记版本限制
直接给LockScreenWidget本身添加@available注解,WidgetBundle的代码可以保持简洁:
@available(iOSApplicationExtension 16.0, *) struct LockScreenWidget: Widget { // 锁屏组件的实现代码 } struct WidgetBundler: WidgetBundle { @WidgetBundleBuilder var body: some Widget { HomeScreenWidget() LockScreenWidget() } }
方式二:在WidgetBundle中给锁屏组件实例加版本注解
如果不想修改LockScreenWidget的定义,也可以直接在WidgetBundle里给组件实例添加版本限制:
struct WidgetBundler: WidgetBundle { @WidgetBundleBuilder var body: some Widget { HomeScreenWidget() @available(iOSApplicationExtension 16.0, *) LockScreenWidget() } }
这两种写法的效果一致:
- iOS16及以上系统会同时加载主屏和锁屏组件
- iOS14、15系统会自动忽略
LockScreenWidget,只加载HomeScreenWidget - 代码结构更清晰,避免了
WidgetBundle中冗余的分支逻辑
内容的提问来源于stack exchange,提问作者bmeikle
相关产品推荐
相关产品推荐

