选项卡视图在为SwiftUI设置动画的选项卡之间切换

选项卡视图在为SwiftUI设置动画的选项卡之间切换,swiftui,tabview,Swiftui,Tabview,我有一个选项卡,我想在页面之间进行动画切换,如下所示: 是否可以使用SwiftUI?我实际上刚刚使用SwiftUI实现了这一点。以下是我所做的: 1) 创建一个符合UIViewControllerRepresentable的SwiftUI视图。我使用init方法为它提供了一个类型为AnyView的SwiftUI视图数组。在makeUIViewController和updateUIViewController方法中有一些工作要做,所以我们将回到这一点 我创建了一个typealias来传递一组视

我有一个
选项卡
,我想在页面之间进行动画切换,如下所示:


是否可以使用SwiftUI?

我实际上刚刚使用SwiftUI实现了这一点。以下是我所做的:

1) 创建一个符合
UIViewControllerRepresentable的SwiftUI视图。
我使用init方法为它提供了一个类型为
AnyView的SwiftUI视图数组。
makeUIViewController
updateUIViewController
方法中有一些工作要做,所以我们将回到这一点

我创建了一个
typealias
来传递一组视图、它们的图像名称(假设您使用的是系统图像)和视图名称。看起来是这样的:

typealias TabBarItemView=(视图名称:String,图像名称:String,目标视图:AnyView)

2) 您需要创建一个符合
UITabBarControllerDelegate的类。
在该委托中,您可以覆盖
tabBarController(utabbarcontroller:UITabBarController,animationcontrollerfortransitionfromvc:UIViewController到vc:UIViewController)->UIViewControllerInitiatedTransitioning
方法

这部分要求您创建另一个类,一个符合
UIViewControllerAnimatedTransitioning的类。
该类要求您实现两个函数:
transitionDuration(使用transitionContext:UIViewControllerContextTransitioning?)->TimeInterval
,只需指定动画的持续时间

第二个函数是
animateTransition(使用transitionContext:UIViewControllerContextTransitioning)
,它要求您执行一些较重的提升。在此函数中,需要设计移动视图的动画。基本上,您应该应用一个
cGraffeTransform
,将视图从屏幕外移动到屏幕上(想象一个舞台在屏幕的左侧或右侧),同时将另一个视图以相同的方向移出屏幕。在函数结束时,可以使用以下方法设置变换的动画:

UIView.animate(withDuration: animationDuration, animations: moveViewsClosure, completion: cleanUpClosure)
其中,
animationDuration
指定这将需要多长时间,
moveViewsClosure
正在应用变换,
cleanUpClosure
实际上正在用另一个视图替换视图

一旦类符合
UIViewControllerAnimatedTransitioning
的要求,您应该能够将其作为
UIViewControllerAnimatedTransitioning
函数的输出返回

3) 现在您已经创建了代理和动画类,可以将代理分配给我们在中开始的SwiftUI视图中的
UITabViewController
。在结构的顶部,我创建了一个
UITabViewController
类型的变量,并使用了默认的初始值设定项。在
init
函数中,应该将委托设置为我们上面创建的委托类的实例

4) 现在我们可以实现
makeUIViewController
updateUIViewController
功能。在
makeUIViewController
中,您需要使用
UIHostingController
加载视图数组,以使您的SwiftUI视图位于UIKit视图控制器中。加载所有视图后,可以从顶部返回
UITabViewController
。在
更新IViewController
中,您可能需要将委托重置为视图控制器。因为SwiftUI使用结构,所以在更新视图时重新创建视图的情况并不少见;我发现它会丢失对代理的引用,这就是我解决它的方法

我意识到我可以提供我所有的代码,但它相当长,我认为如果您理解这个过程,您将有一个更容易的时间进行故障排除