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

Compose Multiplatform iOS端截图显示空白问题求助

iOS端截图空白问题的解决思路

下面针对你遇到的Compose Multiplatform iOS端截图空白问题,给出几个关键修复点:

  • 替换过时的窗口获取逻辑
    iOS 13+版本里,UIApplication.shared.keyWindow已经被弃用,多场景(Scene)模式下也拿不到正确的当前活跃窗口。改成通过场景获取:

    val window = UIApplication.sharedApplication.connectedScenes
        .filterIsInstance<UIWindowScene>()
        .firstOrNull()?.windows?.firstOrNull { it.isKeyWindow } ?: return null
    
  • 用drawHierarchy替代renderInContext
    renderInContext是iOS旧API,没法正确捕获现代UIKit视图(包括Compose渲染的内容),换成drawHierarchyInRect才能拿到正确的画面:

    UIGraphicsBeginImageContextWithOptions(window.bounds.size, false, UIScreen.mainScreen.scale)
    window.drawHierarchyInRect(window.bounds, afterScreenUpdates = true)
    val uiImage = UIGraphicsGetImageFromCurrentImageContext() ?: return null
    UIGraphicsEndImageContext()
    

    这里传入屏幕缩放比例UIScreen.mainScreen.scale能保证截图清晰度,afterScreenUpdates = true确保视图渲染完成再截图。

  • 必须在主线程执行截图
    UI操作只能在主线程跑,否则会出现捕获失败的情况,把整个截图逻辑包在主线程同步块里:

    DispatchQueue.mainQueue.sync {
        // 所有截图逻辑放在这里
    }
    
  • 如果是特定Compose视图截图,不要截整个窗口
    如果只需要截某个Compose组件,给目标组件加Modifier.onIOSView { view -> ... }保存对应的UIView实例,然后对这个view执行截图逻辑,而不是整个窗口。

完整修正后的代码

class IosScreenshot : ScreenshotInterface {
    override fun takeScreenshot(): String? {
        var screenshotBase64: String? = null
        DispatchQueue.mainQueue.sync {
            // 获取当前活跃窗口
            val window = UIApplication.sharedApplication.connectedScenes
                .filterIsInstance<UIWindowScene>()
                .firstOrNull()?.windows?.firstOrNull { it.isKeyWindow } ?: return@sync

            // 创建适配的图片上下文
            UIGraphicsBeginImageContextWithOptions(window.bounds.size, false, UIScreen.mainScreen.scale)
            // 绘制完整视图层级
            window.drawHierarchyInRect(window.bounds, afterScreenUpdates = true)
            
            val uiImage = UIGraphicsGetImageFromCurrentImageContext() ?: run {
                UIGraphicsEndImageContext()
                return@sync
            }
            UIGraphicsEndImageContext()

            // 转换为Base64字符串返回
            val imgData = UIImagePNGRepresentation(uiImage)
            screenshotBase64 = imgData?.base64EncodedStringWithOptions(NSDataBase64Encoding64CharacterLineLength)
        }
        return screenshotBase64
    }
}

内容的提问来源于stack exchange,提问作者Phillipp Correia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 02:42:29