SwiftUI 如何有下一个和后退动画?

Posted

技术标签:

【中文标题】SwiftUI 如何有下一个和后退动画?【英文标题】:SwiftUI how to have next and back animations? 【发布时间】:2020-09-07 18:17:26 【问题描述】:

我制作了包含 3 个页面和“下一步”、“返回”按钮的示例应用程序。

当我点击“下一步”时,动画效果很完美:旧内容向左走,新内容从右走。

但是,我正在努力让“Back”动画同时运行良好。

目标:单击“返回”时,旧内容应向右移动,新内容应从左侧显示。 (“Back”的动画应该与“Next”的动画相反)

知道如何做到这一点吗?

下面是“下一个”的完美过渡

struct ContentView: View 
    @State var page: Int = 0
    
    var body: some View 
        
        VStack 
            HStack 
                Button(action:  withAnimation()  self.page = self.page - 1  ) 
                    Text("Back")
                
                
                Spacer()
                
                Button(action:  withAnimation()  self.page = self.page + 1 ) 
                    Text("Next")
                
            
            Spacer()
            
            if page == 0 
                PageView(name: "First page", color: .brown)
                    .transition(AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)))
             else if page == 1 
                PageView(name: "Second page", color: .systemGreen)
                    .transition(AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)))
             else if page == 2 
                PageView(name: "Third page", color: .systemBlue)
                    .transition(AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)))
            
        
    


struct PageView: View 
    var name: String
    var color: UIColor
    var body: some View 
        HStack 
            Spacer()
            Text(name)
            Spacer()
        
        .padding()
        .padding(.vertical, 50)
        .background(Color(color))
    

【问题讨论】:

【参考方案1】:

导航返回时需要反转过渡。

这是一种可能的方法(也在一个地方进行了过渡,并更正了动画以在任何地方工作,包括预览)。

使用 Xcode 12 / ios 14 测试。

struct ContentView: View 
    @State var page: Int = 0

    @State private var isBack = false   // << reverse flag (not animatable)
    var body: some View 

        VStack 
            HStack 
                Button(action: 
                    self.isBack = true
                    self.page = self.page - 1
                ) 
                    Text("Back")
                

                Spacer()

                Button(action: 
                    self.isBack = false
                    self.page = self.page + 1
                ) 
                    Text("Next")
                
            
            Spacer()

            Group 
                if page == 0 
                    PageView(name: "First page", color: .brown)
                 else if page == 1 
                    PageView(name: "Second page", color: .systemGreen)
                 else if page == 2 
                    PageView(name: "Third page", color: .systemBlue)
                
            .transition(AnyTransition.asymmetric(
                insertion:.move(edge: isBack ? .leading : .trailing),
                removal: .move(edge: isBack ? .trailing : .leading))
            )
            .animation(.default, value: self.page)   // << animate here by value
        
    

【讨论】:

以上是关于SwiftUI 如何有下一个和后退动画?的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:动画列表中的圆圈

SwiftUI:如何使用延迟在两个图像之间设置动画过渡?

在 SwiftUi 中禁用默认按钮单击动画

SwiftUI 在选项卡之间导航的正确方式

带有 navigationLink 的 SwiftUI 消失后退按钮

如何在 SwiftUI 中停止 Animation().repeatForever