SwiftUI 如何有下一个和后退动画? [英] SwiftUI how to have next and back animations?

查看:23
本文介绍了SwiftUI 如何有下一个和后退动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我制作了 3 页的示例应用程序,然后下一步"、返回"按钮.

I made sample app with 3 pages and "Next", "Back" buttons.

当我点击下一步"时动画很完美:旧内容在左边,新内容在右边.

When I click "Next" animation is perfect: the old content goes to the left and new content comes from the right.

但是,我正在努力使返回"动画同时工作得很好.

However, I'm struggling to make "Back" animation to work nice simultaneously.

目标:点击返回"时旧内容应该在右边,新内容应该从左边来.(Back"的动画应该与Next"的动画相反)

Goal: when clicking "Back" old content should go to the right and new content should come from the left. (animation for "Back" should be reverse to animation for "Next")

知道如何做到这一点吗?

Any idea how to accomplish this?

下面是下一步"的完美过渡

Below is perfectly working transition for "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))
    }
}

推荐答案

返回时需要反向转换.

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

Here is possible approach (also made transition in one place and corrected animation to work everywhere, including Preview).

使用 Xcode 12/iOS 14 测试.

Tested with 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 如何有下一个和后退动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆