https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
v

Vinicius Matheus

10/21/2023, 8:39 PM
Hi everyone, I just started my studies on Compose Multiplatform. I come from an Android background, and I know nothing about iOS. So, I’m working on a personal project, and I was trying to change the color of the status bar on both platforms based on the theme. The Android side was easy, but I struggled on the iOS side. I couldn’t find a clear path to this, and I came up with this solution based on some approaches to changing the color of the status bar in Swift. I don’t know if there is another way to do this. I would appreciate any advice, thanks!
Copy code
// main.android.kt
@Composable
actual fun setStatusBarColor(color: Color, isDark: Boolean) {
    val view = LocalView.current
    if (!view.isInEditMode) {
        SideEffect {
            val window = (view.context as Activity).window
            window.statusBarColor = color.toArgb()
            WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !isDark
        }
    }
}
Copy code
// main.ios.kt
@Composable
actual fun setStatusBarColor(color: Color, isDark: Boolean) {
    val statusBarColor = UIColor(
        CIColor(
            color.red.toDouble(),
            color.green.toDouble(),
            color.green.toDouble(),
            color.alpha.toDouble(),
        ),
    )

    UIApplication
        .sharedApplication
        .keyWindow
        ?.windowScene
        ?.statusBarManager
        ?.statusBarFrame()
        ?.let {
            UIView(it)
        }?.apply {
            setBackgroundColor(statusBarColor)
        }?.let {
            UIApplication.sharedApplication.keyWindow?.addSubview(it)
        }
}
u

लातों वाला भूत

10/22/2023, 4:59 PM
Unfortunately this is the only way to do this iOS 13+. Previous versions were a bit more simple but now this is the right way. Custom themed color for safe area in iOS is a bit of a headache because iOS intentionally wants apps to adhere to black/white for safe area.
Copy code
val colorScheme = when {
        isDynamicColorAvailable && darkTheme -> dynamicDarkColorScheme(context)
        isDynamicColorAvailable -> dynamicLightColorScheme(context)
        darkTheme -> DarkColors
        else -> LightColors
    }
This way you can have themed color schemes. So its easier to make the switch.
Copy code
val colorScheme = if (darkTheme) DarkColors else LightColors

    val statusBarColor = UIColor(CIColor(
        red = colorScheme.surfaceVariant.red.toDouble(),
        green = colorScheme.surfaceVariant.green.toDouble(),
        blue = colorScheme.surfaceVariant.blue.toDouble(),
        alpha = colorScheme.surfaceVariant.alpha.toDouble(),
    ))

    UIApplication
        .sharedApplication
        .keyWindow
        ?.windowScene
        ?.statusBarManager
        ?.statusBarFrame()
        ?.let {
            UIView(it)
        }?.apply {
            setBackgroundColor(statusBarColor)
        }?.let {
            UIApplication.sharedApplication.keyWindow?.addSubview(it)
        }
Maybe a neater way would be to build an extension around UIColor for setting theme color values.
1
v

Vinicius Matheus

10/23/2023, 12:51 PM
Great! Thanks 🙂
7 Views