Search code examples
ioscompose-multiplatform

Screenshot showing up blank in Compose Multiplatform for iOS


I've been trying to implement ability to take a screenshot for both Android and iOS using Compose Multiplatform but for iOS is returning a blank image. Android works as expected.

Please find below the code that I am using. Any thoughts?

class IosScreenshot : ScreenshotInterface {
    override fun takeScreenshot(): String? {
        val window = UIApplication.sharedApplication.keyWindow ?: return null
        UIGraphicsBeginImageContextWithOptions(window.bounds.useContents { CGSizeMake(size.width, size.height) }, false, 0.0)
        window.layer.renderInContext(UIGraphicsGetCurrentContext())
        val uiImage = UIGraphicsGetImageFromCurrentImageContext() ?: return null
        UIGraphicsEndImageContext()
        val img = UIImagePNGRepresentation(uiImage)
        return img?.base64EncodedStringWithOptions(options = NSDataBase64Encoding64CharacterLineLength)
    }
}

Solution

  • The issue is from how the view's layer is being rendered. try replacing layer.render(in:) with drawHierarchy(in:afterScreenUpdates:)

    Sample

    class IosScreenshot : ScreenshotInterface {
        override fun takeScreenshot(): String? {
          guard let window = UIApplication.shared.keyWindow else { return nil }
          UIGraphicsBeginImageContextWithOptions(window.bounds.size, false, 0.0)
        
        // Make sure the complete view hierarchy is rendered.
          window.drawHierarchy(in: window.bounds, afterScreenUpdates: true)
        
          guard let uiImage = UIGraphicsGetImageFromCurrentImageContext() else {
            UIGraphicsEndImageContext()
            return nil
        }
        UIGraphicsEndImageContext()
        
    
        guard let img = UIImagePNGRepresentation(uiImage) else { return nil }
        return img.base64EncodedString(options: .lineLength64Characters)
       }
    }