I'm trying to get a nice transition for a view that needs to display date. I give an ID to the view so that SwiftUI knows that it's a new label and animates it with transition. Here's the condensed version without formatters and styling and with long duration for better visualisation:
struct ContentView: View {
@State var date = Date()
var body: some View {
VStack {
Text("\(date.description)")
.id("DateLabel" + date.description)
.transition(.slide)
.animation(.easeInOut(duration: 5))
Button(action: { date.addTimeInterval(24*60*60) }) {
Text("Click")
}
}
}
}
Result, it's working as expected, the old label is animating out and new one is animating in:
But as soon as I wrap it inside UIHostingController:
struct ContentView: View {
@State var date = Date()
var body: some View {
AnyHostingView {
VStack {
Text("\(date.description)")
.id("DateLabel" + date.description)
.transition(.slide)
.animation(.easeInOut(duration: 5))
Button(action: { date.addTimeInterval(24*60*60) }) {
Text("Click")
}
}
}
}
}
struct AnyHostingView<Content: View>: UIViewControllerRepresentable {
typealias UIViewControllerType = UIHostingController<Content>
let content: Content
init(content: () -> Content) {
self.content = content()
}
func makeUIViewController(context: Context) -> UIHostingController<Content> {
let vc = UIHostingController(rootView: content)
return vc
}
func updateUIViewController(_ uiViewController: UIHostingController<Content>, context: Context) {
uiViewController.rootView = content
}
}
Result, the new label is not animated in, rather it's just inserted into it's final position, while the old label is animating out:
I have more complex hosting controller but this demonstrates the issue. Am I doing something wrong with the way I update the hosting controller view, or is this a bug in SwiftUI, or something else?