SwiftUI how to have next and back animations?

和自甴很熟 提交于 2021-02-15 07:04:47

问题


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.

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))
    }
}

回答1:


You need to reverse transition when navigating back.

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

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
        }
    }
}


来源:https://stackoverflow.com/questions/63782469/swiftui-how-to-have-next-and-back-animations

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!