I’ve been play with `UIKitView` and a `UIImageView...
# compose-ios
j
I’ve been play with
UIKitView
and a
UIImageView
being created in the factory. The image is a SF Symbol/system image so it’s got a transparent background. However whatever I try and set, either the
backgroundColor
of the
UIImageView
or the modifier of the compose component, it’s always white, not clear/transparent. Example snippet here:
Copy code
@Composable
actual fun SystemImageView(name: String, modifier: Modifier) {
    val systemImage = remember { UIImage.systemImageNamed(name) }
    UIKitView(
        factory = {
            UIImageView(systemImage).apply {
                opaque = false
                backgroundColor = UIColor.clearColor
                contentMode = UIViewContentMode.UIViewContentModeScaleAspectFit
                tintColor = UIColor.orangeColor
            }
        },
        modifier = modifier
    )
}
It feels like somewhere there’s a wrapping view which has a default background colour I can’t access. Any help appreciated. 🙇
I’ve seen this with other things as well, like when playing with wrapping some other views (like
UIScrollView
, which has other issues I may ask about another day 🙃). So I’m wondering if it’s something coming from
UIKitView
or `InteropView`/`UIKitInteropViewHolder`. I see that the other way, the config for
ComposeUIViewController
has an
opaque
option, but there doesn’t seem to be an option this way.
a
Hi! Unfortunately we're not supporting transparent background for interop views for now.
j
Ok thanks, I’ll stop falling down that rabbit hole. 🙃 Is that something that might come in the future, or just not possible?
j
Is there a feature request ticket in youtrack that we might be able to star / follow along?
👀 1
a
You don’t actually need a native view to display SF symbol.
Copy code
fun ImageBitmap.Companion.systemImage(systemName: String) : ImageBitmap {
    return requireNotNull(UIImage.systemImageNamed(systemName)) {
        "Image with name $systemName not found"
    }.toComposeImageBitmap()
}


@OptIn(ExperimentalForeignApi::class)
fun UIImage.toComposeImageBitmap() : ImageBitmap {

    val bytes = requireNotNull(UIImagePNGRepresentation(this)) {
        "Failed to get PNG representation of image"
    }

    val byteArray = ByteArray(bytes.length.toInt())

    byteArray.usePinned {
        memcpy(it.addressOf(0), bytes.bytes, bytes.length)
    }

    return Image.makeFromEncoded(byteArray)
        .toComposeImageBitmap()
}
i
> Is that something that might come in the future, or just not possible? The current trick is placing interop view under compose canvas and cut transparent hole in compose. In this approach there is no way to see Compose content under the interop view. Why? 1. Ability to place Compose content above interop (it was much more expected than transparency) 2. Ability to cut not rectangular shape (clip/shadow modifiers works) Re-rendering iterop view inside compose canvas is possible but perf costly, so postponed for now. In general I guess current way is solid default, and other approaches will be just an alternatives to handle more cases in the future
j
@Alexander Zhirkevich Oh interesting. I was thinking about exporting the reference, but this is doing it live at runtime. Do you see any performance hits doing it this way?
@Ivan Matkov Thanks for the explanation. I can see the difficulties for sure. I’ll keep track of that YT @Andrei Salavei (thanks for that 🙇 ) and play with the other suggestion for now. There’s a few cases where we might not need this, and can just use the same colour as the background, but it’s good to know the right/best ways to do it for now if needed 🙂
a
No issues, just remember the resulting bitmap. It probably can cause a little junk in lazy scrollable layouts with many sf symbols, but you can do all the decoding stuff in the background thread in such case
👍 1
a
The best approach is to minimize the number of interop view inserts because it might slow down your application. The suggestion by @Alexander Zhirkevich is good for the current needs. However for a long-term solution I would recommend creating (or just getting) own set of vector icons - it will increase performance and reduce memory footprint. There are lots of tutorials how to do it.
👍 1