You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 12:48:23