Compose Multiplatform 1.10 Interop views 新特性:Overlay 和 Autosizing

近日,在 CMP 的 1.10 更新里,官方提及了两个关于 Interop views 的全新特性:Overlay 和 Autosizing ,核心目的就是解决 Compose Multiplatform 在"嵌入原生 UI 组件(interop views)"时最头疼的两件事:层级(z-order)和尺寸(measure/layout)

Interop View ≈ Flutter 里的 PlatformView 。

一、Overlay

Overlay placement for interop views 的主要作用就是:让 UIKit interop 真正能"盖在"Compose 上

kotlin 复制代码
@OptIn(ExperimentalComposeUiApi::class)
UIKitViewController(
    modifier = modifier,
    factory = { factory.createNativeMap() },
    update = {},
    properties = UIKitInteropProperties(placedAsOverlay = true)
)

在过去,我们可以使用 UIKitView / UIKitViewController 把 iOS 原生控件嵌到 Compose 里,而这次 1.10 增加了一个 实验性开关:UIKitInteropProperties.placedAsOverlay = true,主要目的就是让这些 UIKit interop 视图可以放在 Compose UI 之上

核心目的就是 interop view 可以更好地支持透明背景和原生 shader / 特效 ,这对于现在全新的 iOS 26 Liquid Glass 场景来说尤为重要。

简单来说,在之前,iOS 上的 interop view 更像 Underlay ,不严谨的说,就类似 : UIKit 在下,Compose 在上,Compose 需要"让出一个洞/区域"让 UIKit 露出来

因为 Compose (Skia) 和 UIKit view 不在同一渲染树里,所以默认 interop 实现更偏向"在 Compose 里留出空间让 UIKit 显示",所以视觉效果就像 hole punching。

这种情况下 iOS 的 Interop views 无法实现毛玻璃/半透明覆盖,因为原生 View 在下面,你无法让原生 View 变成半透明盖在 Compose 内容上。

所以你会发现,在之前,当你需要 blur 的时候,看到的不是 Compose 而是黑底或 window 底色" ,这是因为 "UIKit 的半透明/blur 采样不到 Skia 的内容" 。

而现在 1.10 提供了新的可能,interop view 可以通过配置提升到 Compose/Skia 渲染层上方成为真正的 overlay,这时候原生半透明背景、shader、blur 等效果就可以正确叠加在 Compose 上,当然,同时代价是同区域 Compose 可能会被遮挡/点击被原生 view 吃掉。

虽然实现上不是 Flutter HC 那种合成路径,但是表现形式上和类似。

总结一下就是:之前 iOS 上的 interop view 只能做"底图",不能做"蒙层" ,现在可以开始追求 iOS 原生质感的效果了

Autosizing

从 1.10 开始,CMP 对 interop view 加了 Autosizing :

  • Desktop(Swing)SwingPanel 会根据嵌入 Swing 组件的 minimum / preferred / maximum size 自动调整自身尺寸
  • iOS(UIKit) :UIKit interop view 支持按视图的 fitting size / intrinsic content size 来决定大小,从而能更好地 wrap content

简单说就是:你不用再手算尺寸、也不用提前写死宽高

并且特别提到一个大痛点的解法:在 iOS 上,这让你通过 UIHostingController 包 SwiftUI 的时候,更容易做到正确的"内容包裹"。

为什么这又是一个大更新内容?因为在 Compose 的世界里,布局是"先测量、再布局",而过去 interop view 最大的问题是:

  • Compose 不知道原生 view 的"理想尺寸",导致常常必须:
    • Modifier.size(...) 写死;
    • 或者自己去桥接 native 的测量逻辑,再把结果喂给 Compose
  • 一旦内容变化(比如 SwiftUI 文本变化、Swing 组件 preferredSize 变了),还要触发重算

Autosizing 相当于把 interop 的测量链路补齐了,让 interop 更接近 Compose 原生组件的体验:能 wrap content,能随内容变化而重新测量

这个基础上,SwiftUI 视图(通过 UIHostingController )和不依赖 NSLayoutConstraints 的 basic UIView 子类能更方便适配封装。

也就是说这个更新,可以简化了混合开发时的布局工作,让原生组件能像 Compose 原生组件一样自然地"撑开"布局。

最后

至于你肯定会说,那为什么不说 Andorid ?那肯定是因为 CMP 是基于 Compose 实现的啊,Compose Android 本质上还是嵌在 Android View 系统里,ComposeView 是一个 Android View,跑在同一个 View hierarchy 里:

Compose 和 Android View 一开始就属于同一个"生态",同一种坐标系、同一种生命周期、同一种事件分发。

所以当你用 AndroidView {} 嵌一个原生 View 的时候,它没有"Skia vs UIKit 两个体系隔离"这种割裂,最典型的就是 SurfaceViewAndroidView 里可以正常工作:

Compose 和「传统 View」 共用同一个 Window 和 DecorViewAndroidView 作为一个桥接节点,将「传统 View」 "插入" 到 Compose 的布局树中,虽然 SurfaceView 绘制内容是独立的,但在屏幕上是共享一个 WindowSurfaceFlinger 依然会统一管理窗口合成。

这部分在之前的 《深入 Flutter 和 Compose 的 PlatformView 实现对比,它们是如何接入平台控件》 有了聊过,感兴趣可以看看。

参考链接

https://kotlinlang.org/docs/multiplatform/whats-new-compose-110.html

相关推荐
灰灰勇闯IT1 天前
Flutter for OpenHarmony:图标与 Asset 资源管理 —— 构建高性能、可维护的视觉资源体系
flutter
0wioiw01 天前
Onesignal(Xcode)
ide·macos·xcode
子春一1 天前
Flutter for OpenHarmony:构建一个 Flutter 记忆翻牌游戏,深入解析状态管理、动画交互与经典配对逻辑
flutter·游戏·交互
南宫码农1 天前
我的电视 - Android原生电视直播软件 完整使用教程
android·开发语言·windows·电视盒子
道亦无名1 天前
音频数据特征值提取 方法和步骤
android·音视频
Lancker1 天前
定制侠 一个国产纯血鸿蒙APP的诞生过程
android·华为·智能手机·鸿蒙·国产操作系统·纯血鸿蒙·华为鸿蒙
2601_949847751 天前
Flutter for OpenHarmony音乐播放器App实战13:歌手列表实现
flutter
雨季6661 天前
破界与共生:HarmonyOS原生应用生态全景图谱与PC时代三重变局
flutter·华为·harmonyos
哈基米~南北绿豆1 天前
虚拟机体验:在Windows/Mac上运行鸿蒙PC开发环境
windows·macos·harmonyos
西西学代码1 天前
Flutter---电流电压横向滑动折线图
flutter