导航时如何在 SwiftUI 中使用自定义视图转换?

Posted

技术标签:

【中文标题】导航时如何在 SwiftUI 中使用自定义视图转换?【英文标题】:How to use custom view transitions in SwiftUI when navigating? 【发布时间】:2020-08-19 20:37:19 【问题描述】:

在基于 UIKit 的应用程序中,我们可以使用 UIViewControllerAnimatedTransitioning 协议进行自定义导航转换。

在 SwiftUI 中是否有等价物?

我知道我们已经可以在删除和添加视图之间进行动画处理。 但是当我们 push 和 pop 到导航堆栈时,我们怎么做呢?

【问题讨论】:

标准 NavigationView 目前不允许自定义转换。您可以改用/创建自定义导航。例如考虑这个解决方案***.com/a/59087574/12299030 @Asperi 这是一个糟糕的建议。这基本上破坏了 UINavigationController 内置的任何可访问性支持,以及提供的所有内置工具。就像网络“应用程序”这样做很糟糕一样,SwiftUI 也同样糟糕。 正确的解决方案是要么手动封装 UINavigationController,要么获取对它的引用,比较简单。 【参考方案1】:

到目前为止,SwiftUI 的 API 中还没有类似的东西可用。确保向 Apple 提出增强请求。

自己实现“导航”是一个糟糕的主意,因为您基本上提供了UINavigationController 提供的所有可访问性和设施支持。

相反,这里有一个建议:

通过自定义 SwiftUI 视图或修饰符,将 NavigationView 包装为 UIViewControllerRepresentable 包装器,然后设置 UIHostingController 子类,等待调用 addChild(_:),这将是导航控制器作为宿主控制器的子级添加。从这里开始,如果您的动画是“静态的”(例如,不需要任何子视图到子视图的转换),您可以通过实现导航控制器委托并提供动画控制器来完成此操作。

如果您确实需要更高级的过渡(例如 Photos.app 的照片过渡),您可以创建一个自定义的 UIViewRepresentable 包装器,它将用作“来自”视图和“到”视图的标记,然后您可以使用那些在 UIKit 中发现的,例如可以在过渡中进行快照和动画处理。

提议的 API 如下所示:

struct ContentView1: View 
    var body: some View 
        NavigationLink(destination: DetailView()) 
            Image("small").customSourceTarget()
        .navigationBarTitle("Navigation")  
    


struct ContentView2: View 
    var body: some View 
        Image("large").customTransitionTarget()
    


NavigationView 
    ContentView1()
.customAnimatable()

【讨论】:

以上是关于导航时如何在 SwiftUI 中使用自定义视图转换?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 视图中包装 UIBarButtonItem?

SwiftUI 如何获取自定义幻灯片转换的视图大小?

SwiftUI:导航链接中的自定义标签显示为灰色

SwiftUI 中的自定义模态转换

视图是黑色的,当返回到导航控制器堆栈视图时,在实现自定义转换后

如何在使用自定义用户代理的 SwiftUI 中创建 Safari 视图?