JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
15.27k stars 1.11k forks source link

WkWebView inside a UIKit View is not displayed when height is fixed and used inside a LazyColumn Item #4913

Closed Vaibhav2002 closed 3 weeks ago

Vaibhav2002 commented 4 weeks ago

Describe the bug When using a WkWebView inside a UIKit view without setting a fixed height using Modifier.height() inside a LazyColumn Item, it is not displayed When a fixed height it set, it is displayed.

Affected platforms

Versions

To Reproduce Steps to reproduce the behavior:

  1. Run this code snippet:

    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.spacedBy(8.dp),
        contentPadding = PaddingValues(16.dp),
    ) {
        items(30, contentType = { it }) {
            ListItem(modifier = Modifier.fillParentMaxWidth())
        }
    }
    
    @Composable
    fun ListItem(modifier: Modifier = Modifier) {
        Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(8.dp)) {
            Box(modifier = Modifier.fillMaxWidth().background(Color.Red).height(30.dp))
            Box(modifier = Modifier.fillMaxWidth().background(Color.Green).height(64.dp))
            NativeWebView(
                url="https://youtube.com"
                modifier = Modifier.fillMaxWidth(),
            )
            Box(modifier = Modifier.fillMaxWidth().background(Color.Blue).height(30.dp))
        }
    }
    
    @OptIn(ExperimentalForeignApi::class)
    @Composable
    actual fun NativeWebView(url: String, modifier: Modifier) {
        UIKitView(
            factory = {
                val config =
                    WKWebViewConfiguration().apply {
                        allowsInlineMediaPlayback = true
                        defaultWebpagePreferences.allowsContentJavaScript = true
                        preferences.javaScriptEnabled = true
                    }
                WKWebView(
                    frame = CGRectZero.readValue(),
                    configuration = config,
                ).apply {
                    setOpaque(false)
                }
            },
            modifier = modifier,
            onRelease = {},
            update = {
               it.loadRequest(NSMutableURLRequest.requestWithURL(URL = NSURL(string = url)))
            }
        )
    }

Screenshots

When fixed height Modifier.height(400.dp) applied to NativeWebView, It looks fine

image

Without fixed height:

image

Additional context

My use case is to embed Tweets, Reddit Post, Yt Videos and other embeddable html in a LazyColumn Item

elijah-semyonov commented 3 weeks ago

Interop views don't support sizing based on intrinsic content size of native views (and most likely won't be, Compose and UIKit have different layout systems). Moreover, WKWebView doesn't have any intrinsic size. These closest you can get to mimic it is - https://stackoverflow.com/questions/27515236/how-to-determine-the-content-size-of-a-wkwebview and provide it explicitly.