iOS App小组件(Widget)设置透明背景

在iOS中实现小组件的透明背景。无法通过现有的API显示桌面背景,因为小组件自带默认背景,目前来看只能使用私有API。

项目Demo

从GitHub下载项目Demo,运行该项目,在iOS 16版本的模拟器中,可以看到小组件的背景是透明的。

注意,这个项目Demo只能在iOS 16模拟器中,新增小组件。在iOS 15版本的真机和模拟器中,无法查看到这个项目Demo的小组件,怀疑与项目Demo有关。

在这个项目中,实际上只有两个文件(FooObject.h和FooObject.mm文件)需要注意。

其他的文件,例如Info文件为标准配置,MyApp-Bridging-Header文件是自动生成的空白文件,无需创建。

使用方法

1、将FooObject文件复制到实际项目中。

在访达中找到FooObject.h和FooObject.mm文件。

将这两个文件拖入到实际项目中。

2、配置项目名-Bridging-Header.h文件

在拖入项目后,可能会弹出一个窗口,提示创建一个"项目名- Bridging-Header.h"文件,点击"创建"按钮。

如果没有弹出这个窗口,则需要手动创建一个"项目名- Bridging-Header.h"的空文件。

右击Xcode左侧文件列表,选择"New Empty File",输入文件名称。

示例:

css 复制代码
BankletWidget-Bridging-Header.h

"项目名- Bridging-Header.h"文件是一个空文件,其作用为让Swift能识别Objective-C文件。

在Xcode左侧文件列表中,点击项目名称,选择Build Settings → Objective-C Bridging Header,输入"项目名- Bridging-Header.h"文件路径。

示例:

css 复制代码
BankletWidget/BankletWidget-Bridging-Header.h

这是因为在 Xcode 中,如果项目里有 .h/.m/.mm 文件并想在 Swift 中编译通过,就需要配置Build Settings → Objective-C Bridging Header,指定一个头文件路径。

即使该文件是空的,也能让 .mm 文件参与编译。

3、MRC引发的报错

编译项目时,会输出报错信息:

vbnet 复制代码
'release' is unavailable: not available in automatic reference counting mode

这是因为FooObject.mm文件使用旧的(MRC)Objective-C代码,不支持在ARC模式下运行,需要为该文件关闭ARC

4、修改 .mm 文件

获取设置透明背景小组件的kind。

例如:

swift 复制代码
struct BankletWidget: Widget {
    let kind: String = "BankletWidget"  // 获取对应的 kind
    
    var body: some WidgetConfiguration {
        ...
    }
}

修改FooObject.mm文件,将代码中的MyClearWidget修改为,透明背景的小组件kind。

css 复制代码
if ([kind isEqualToString:@"MyClearWidget"])

修改为

css 复制代码
if ([kind isEqualToString:@"BankletWidget"])

如果想要修改为半透明的状态,则将 MyBlurWidget 改为半透明背景的小组件kind。

实现透明背景

在Xcode中运行项目,将应用安装到真机上,配置小组件,可以实现透明背景。

这里使用的是iOS 17真机运行。

总结

iOS App小组件设置透明背景,非常复杂。我大概花费了三天的时间,找寻这一解决方案,最终在X的一个对话中,找到了实现透明背景的GitHub仓库

在这里,非常感谢Christian的贴文分享,以及pookjw分享的透明背景代码。

在iOS App小组件中,因为小组件受SpringBoard(主屏幕管理进程) 严格管控,本质上是SpringBoard截取WidgetKit渲染输出的一张图。

所以,我们无法通过现有的小组件API访问到背景或实现小组件的透明背景。

透明会被系统强制填充为"安全背景"(通常是系统模糊色或白底)。

在这个解决方案中,实际上使用的是私有API/系统内部接口的调用。

CHSMutableWidgetDescriptor 是系统内部(SpringBoard / Home Screen)用于描述 widget 的类或结构体。

通过私有 selector(Objective-C 方法),调用:

ini 复制代码
[widgetDescriptor setBackgroundRemovable:1];
[widgetDescriptor setTransparent:1];
[widgetDescriptor setPreferredBackgroundStyle:1];  // or 2 for blur

这些调用能让系统渲染 widget 背景为"透明层"或模糊层,而不是系统默认的材质背景。

这种方法如果在内部签名或越狱 / 私有环境中使用,使 widget 真正带有透明效果(不是伪裁剪图)。

也就是说,ClearAndBlurredWidgets 的 Swift / Objective-C 代码可能在 widget descriptor 初始化 /注册阶段就插入对私有 API 的调用,从而一开始就告诉系统"我的 widget 背景是透明 /可移除 /模糊样式"。

这种使用私有API的做法,在App Store应用中本身并不符合规定,因为调用私有接口会被审核拒绝、签名校验会失败、未来系统更新可能破坏。

但是,目前App Store中实现透明背景的小组件,大概率也都是使用这一私有API实现透明效果,所以这个私有API在App Store中并没有被严格审核,而是允许其在App Store中上架并使用。

例如,Top Widgets*:

因此,可以使用这一私有API,实现 App 小组件的透明背景效果。

就像Greg Gardner吐槽的那样,苹果应该公开这个API,而不是被其他开发者在App Store中使用。

最后,说明一下,这个GitHub仓库实现的透明背景,在iOS 26中,好像会变为液态波澜,不再是透明效果。

参考文章

1、X:x.com/brocodevs/s...

2、GitHub:github.com/pookjw/Clea...

3、GitHub:github.com/fangjunyu1/...

4、Xcode报错:'release' is unavailable- not available in automatic reference counting mode:fangjunyu.com/2025/10/08/...

5、Greg Gardner:mastodon.social/@gregggreg@...

相关推荐
恋猫de小郭3 小时前
React 和 React Native 不再直接归属 Meta,React 基金会成立
android·前端·ios
HarderCoder17 小时前
Swift 中的基本运算符:从加减乘除到逻辑与或非
ios·swift
HarderCoder17 小时前
Swift 中“特性开关”实战笔记——用编译条件+EnvironmentValues优雅管理Debug/TestFlight/AppStore三环境
ios·swift
HarderCoder17 小时前
Swift 并发任务中到底该不该用 `[weak self]`?—— 从原理到实战一次讲透
ios·swift
FeliksLv18 小时前
iOS 集成mars xlog
ios
2501_9151063220 小时前
CDN 可以实现 HTTPS 吗?实战要点、部署模式与真机验证流程
网络协议·http·ios·小程序·https·uni-app·iphone
大熊猫侯佩2 天前
在肖申克监狱玩转 iOS 26:安迪的 Liquid Glass 复仇计划
ios·swiftui·swift
非专业程序员2 天前
逆向分析CoreText中的字体级联/Font Fallback机制
前端·ios
库奇噜啦呼2 天前
【iOS】简单的四则运算
macos·ios·cocoa