swiftui - 为什么当我在 UIHostingController 中使用 SwiftUI-transition 时,它不能按预期工作?
问题描述
我正在尝试为需要显示日期的视图获得一个很好的过渡。我为视图提供了一个 ID,以便 SwiftUI 知道它是一个新标签并通过过渡对其进行动画处理。这是没有格式化程序和样式的精简版本,并且持续时间较长,以实现更好的可视化:
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")
}
}
}
}
结果,它按预期工作,旧标签正在动画,新标签正在动画:
但是一旦我将它包装在 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
}
}
结果,新标签没有动画,而只是插入到它的最终位置,而旧标签正在动画出来:
我有更复杂的托管控制器,但这说明了这个问题。我更新托管控制器视图的方式是否有问题,或者这是 SwiftUI 中的错误,还是其他什么?
解决方案
状态在不同的托管控制器之间运行不佳(尚不清楚这是限制还是错误,只是经验观察)。
解决方案是在托管视图中嵌入依赖状态。使用 Xcode 12.1 / iOS 14.1 测试。
struct ContentView: View {
var body: some View {
AnyHostingView {
InternalView()
}
}
}
struct InternalView: View {
@State private var date = Date() // keep relative state inside
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")
}
}
}
}
注意:您还可以尝试ObservableObject/ObservedObject
基于视图模型 - 该模式具有不同的生命周期。
推荐阅读
- c# - 如何解决切换按钮/矩形和网格行跨度的问题
- python - Python:使用三重引号的嵌套字典上的字符串格式
- ios - 纯代码构建集合但不执行 UICollectionViewDelegateFlowLayout
- django - 如何优化查询 facebook graph API
- caching - apollo-cache-persist 在 nuxt 中使用 vue-apollo
- c++ - 如何在其他cpp文件中使用嵌套的Q_ENUM,而不是在qml中?
- react-router - 如何使语义-ui-react 选项卡单击使用 react-router NavLink 更新 URL?
- python - 如何在python中删除序列中的行
- javascript - 从内部返回函数返回时,管道不是函数
- javascript - 如何用由数组组成的 ul 列表替换 DOM 元素?