SwiftUI侧面菜单内容视图与动画切换

时间:2019-12-28 18:43:37

标签: swift animation swiftui

我在互联网上找到了许多SwiftUI侧边菜单教程,但是都没有显示如何在内容视图之间切换。因此,我尝试创建一个似乎可行的方法,唯一的问题是当我选择任何菜单项时,内容之间没有过渡动画(除非您在菜单中选择了活动菜单)。 我想知道这是否是个好方法,我需要一些帮助来完成动画...

enter image description here enter image description here

提前谢谢!

import SwiftUI

enum PageSelector {
    case home
    case services
    case testimonials
    case contact
}

struct TestView: View {
    @State private var show: Bool = false
    @State private var pageSelector: PageSelector = .home

    var body: some View {
        ZStack {
            // Background of the menu
            Color.blue.edgesIgnoringSafeArea(.all)

            // Menu items and content selection
            VStack(alignment: .leading, spacing: 10) {
                Spacer()
                MenuItem(action: {
                    self.show.toggle()
                    self.pageSelector = .home
                }, title: "Home", image: "chevron.right")
                MenuItem(action: {
                    self.show.toggle()
                    self.pageSelector = .services
                }, title: "Services", image: "chevron.right")
                MenuItem(action: {
                    self.show.toggle()
                    self.pageSelector = .testimonials
                }, title: "Testimonials", image: "chevron.right")
                MenuItem(action: {
                    self.show.toggle()
                    self.pageSelector = .contact
                }, title: "Contact", image: "chevron.right")
                Spacer()
            }
            // Content
            switchContent(show: show)
                .disabled(show ? true : false)
                .offset(x: show ? 300 : 0)
                .rotationEffect(Angle(degrees: show ? -10 : 0))
                .rotation3DEffect(Angle(degrees: show ? 40: 0), axis: (x: show ? 120 : 0, y: show ? 234 : 0, z: show ? 0 : 0))
                .animation(.spring())
                .edgesIgnoringSafeArea(.all)

            // Menu button
            VStack {
                HStack {
                    Button(action: { self.show.toggle() }) {
                        MenuButton(show: $show)
                    }
                    Spacer()
                }
                Spacer()
            }
        }
    }

    // Switching pages (views)
    func switchContent(show: Bool) -> AnyView {
        switch pageSelector {
        case .home:
            return AnyView(HomeView())
        case .services:
            return AnyView(ServicesView())
        case .testimonials:
            return AnyView(TestiMonialsView())
        case .contact:
            return AnyView(HomeView())
        }
    }
}

struct TestView_Previews: PreviewProvider {
    static var previews: some View {
        TestView()
    }
}


struct MenuItem: View {
    let action: ()->Void
    let title: String
    let image: String

    var body: some View {
        HStack {
            Button(action: action) {
                Image(systemName: image)
                    .foregroundColor(.white)
                    .padding(.horizontal)
                    .font(.footnote)
                Text(title)
                    .foregroundColor(.white)
                    .font(.title)
            }
            Spacer()
        }
    }
}

struct MenuButton: View {
    @Binding var show: Bool

    var body: some View {
        HStack {
            Image(systemName: self.show ? "xmark" : "list.dash")
                .frame(width: 50, height: 50)
                .foregroundColor(self.show ? .blue : .white)
                .background(self.show ? Color.white : Color.blue)
                .cornerRadius(25)
                .scaleEffect(self.show ? 0.6 : 1)
                .shadow(radius: 20)
                .padding()
                .opacity(0.8)
                .animation(.spring())
        }
    }
}

示例视图:

import SwiftUI

struct HomeView: View {
    var body: some View {
        VStack {
            Text("This is Home")
        }
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
        .background(Color.white)
    }
}

struct HomeView_Previews: PreviewProvider {
    static var previews: some View {
        HomeView()
    }
}

2 个答案:

答案 0 :(得分:0)

您需要将布局动画与内容动画分开,如下所示:

                   func switchContent(show: Bool) -> AnyView {

                        return AnyView( HomeSwitchView(pageSelector: self.$pageSelector))

                    }
                }


                struct HomeSwitchView: View  {


                    @Binding var pageSelector : PageSelector

                    var body: some View {

                        var text : String?
                        switch pageSelector {
                            case .home:
                                  text = "home"
                               case .services:
                                   text = "services"
                               case .testimonials:
                                  text = "testimonials"
                               case .contact:
                                  text = "contact"
                        }

                        return   VStack {
                            Text("\(text!)")
                        }
                        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                        .background(Color.blue)
                    }
                }

答案 1 :(得分:0)

首先,从 MenuItems 中删除所有 self.show.toggle(),如下所示:

npm install electron

然后在 switchContent() 上添加 onAppear 修饰符,如下所示:

MenuItem(action: {
                self.pageSelector = .home
            }, title: "Home", image: "chevron.right")

经过测试,这对我有用。