Skip to content

Commit

Permalink
iOS UIKit interop regression fix (#857)
Browse files Browse the repository at this point in the history
  • Loading branch information
elijah-semyonov authored Oct 4, 2023
1 parent e33c294 commit 7bc20a9
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 8 deletions.
51 changes: 49 additions & 2 deletions compose/mpp/demo/src/uikitMain/kotlin/NativePopupExample.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,29 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.mpp.demo.Screen
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.interop.LocalUIViewController
import androidx.compose.ui.interop.UIKitView
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.ComposeUIViewController
import platform.UIKit.UINavigationController
import platform.UIKit.navigationController
import platform.UIKit.*
import platform.Foundation.*
import platform.darwin.dispatch_async
import platform.darwin.dispatch_get_main_queue

/*
* Copyright 2023 The Android Open Source Project
Expand Down Expand Up @@ -64,5 +76,40 @@ private fun NativeNavigationPage() {
}) {
Text("Push")
}

LazyVerticalGrid(GridCells.Fixed(2)) {
items(10) { index ->
var image by remember { mutableStateOf<UIImage?>(null) }

DisposableEffect(Unit) {
val url = NSURL(string = "https://cataas.com/cat/says/$index")
val task = NSURLSession.sharedSession.dataTaskWithURL(url, completionHandler = { data, response, error ->
if (data == null) {
return@dataTaskWithURL
}

image = UIImage(data = data)
})
task.resume()

onDispose {
task.cancel()
}
}

UIKitView(
factory = {
val view = UIImageView()
view.contentMode = UIViewContentMode.UIViewContentModeScaleAspectFill
view.clipsToBounds = true
view
},
Modifier.height(80.dp),
update = {
it.image = image
}
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ fun ComposeUIViewController(
private class AttachedComposeContext(
val scene: ComposeScene,
val view: SkikoUIView,
val interopContext: UIKitInteropContext
) {
private var constraints: List<NSLayoutConstraint> = emptyList()
set(value) {
Expand Down Expand Up @@ -144,6 +145,9 @@ private class AttachedComposeContext(

fun dispose() {
scene.close()
// After scene is disposed all UIKit interop actions can't be deferred to be synchronized with rendering
// Thus they need to be executed now.
interopContext.retrieve().actions.forEach { it.invoke() }
view.dispose()
}
}
Expand All @@ -157,11 +161,6 @@ internal actual class ComposeWindow : UIViewController {
private var isInsideSwiftUI = false
private var safeAreaState by mutableStateOf(PlatformInsets())
private var layoutMarginsState by mutableStateOf(PlatformInsets())
private val interopContext = UIKitInteropContext(
requestRedraw = {
attachedComposeContext?.view?.needRedraw()
}
)

/*
* Initial value is arbitarily chosen to avoid propagating invalid value logic
Expand Down Expand Up @@ -520,6 +519,8 @@ internal actual class ComposeWindow : UIViewController {

val skikoUIView = SkikoUIView()

val interopContext = UIKitInteropContext(requestRedraw = skikoUIView::needRedraw)

skikoUIView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(skikoUIView)

Expand Down Expand Up @@ -685,7 +686,7 @@ internal actual class ComposeWindow : UIViewController {


attachedComposeContext =
AttachedComposeContext(scene, skikoUIView).also {
AttachedComposeContext(scene, skikoUIView, interopContext).also {
it.setConstraintsToFillView(view)
updateLayout(it)
}
Expand Down

0 comments on commit 7bc20a9

Please sign in to comment.