Open FelixSubject211 opened 4 months ago
I found a solution. It may well be that this isn't a bug at all. If so, I'm very sorry for the disruption!
You have to use the updateUIViewController in the calling UIViewControllerRepresentable.
I did it like this:
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
let newViewController = SelectAppointmentViewControllerKt.SelectAppointmentViewController(
bookAppointmentScreenModel: bookAppointmentScreenModel,
appointmentBody: appointmentBody
)
uiViewController.willMove(toParent: nil)
uiViewController.view.removeFromSuperview()
uiViewController.removeFromParent()
uiViewController.addChild(newViewController)
newViewController.view.frame = uiViewController.view.frame
uiViewController.view.addSubview(newViewController.view)
newViewController.didMove(toParent: uiViewController)
}
Felt a bit hacky but it worked
Sorry, I'm not exactly following what you are trying to achieve. Can you create a repro and describe what is the expected behavior?
There is too much information missing.
Your updateUIViewController
will recreate SelectAppointmentViewControllerKt.SelectAppointmentViewController
every time the value of UIViewControllerRepresentable
structure changes, which I don't think is something desired.
Plus creating a UIViewController
inside a UIViewControllerRepresentable
context is a bit novel?
Why not just use another UIViewControllerRepresentable
?
The problem occurs as soon as I call the SelectAppointmentCompose via the SelectAppointmentViewController in SwiftUI.
This function creates a new UIViewController
, that draws Composable
content inside. In your case the Composable
content is SelectAppointmentCompose(bookAppointmentScreenModel, appointmentBody)
. It will recalculate itself using the rules of Compose
whenever values that affect the compose and are coming from bookAppointmentScreenModel
and appointmentBody
change (and the implementation actually reads or writes it). The state in there must be represented as compose.runtime.State
(using mutableStateOf
APIs and similar) otherwise Compose will not see them changing and hence won't be reacting.
Then the compose is not redrawn with new calls, although SelectAppointmentViewController is called with new parameters
It's not exactly clear what's happening in here. Do you mean, that parameters used by UIViewControllerRepresentable
structure changed, but the ComposeUIViewController
did not redraw? SwiftUI will try not to call makeUIViewController
of UIViewControllerRepresentable
unless it indeeds needs to make a new one and will only call updateUIViewController
so you can update your data. In your case models should be created on Kotlin side and changed from within this callback, this way Compose
will see the change in State
and redraw accordingly.
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
Hello I have
fun SelectAppointmentViewController( bookAppointmentScreenModel: BookAppointmentScreenModel, appointmentBody: AppointmentBody ) = ComposeUIViewController { MaterialTheme(colors = ColorSystem.ColorPalette()) { SelectAppointmentCompose(bookAppointmentScreenModel, appointmentBody) } }
When I start the app in Android the SelectAppointmentCompose is updated. When the app starts from MainViewController in IOS also.
The problem occurs as soon as I call the SelectAppointmentCompose via the SelectAppointmentViewController in Swiftui. Then the compose is not redrawn with new calls, although SelectAppointmentViewController is called with new parameters