In this tutorial we will create a side menu with a smooth slide-out animation
ContentView.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | // // ContentView.swift // Test // // Created by Cairocoders // import SwiftUI struct ContentView: View { @State var showMenu = false var body: some View { let drag = DragGesture() //swipe to close menu .onEnded { if $0.translation.width < -100 { withAnimation { self.showMenu = false } } } return NavigationView { //geometry property to adjust the frame of our Home View to fill the entire screen. GeometryReader { geometry in ZStack(alignment: .leading) { Home(showMenu: self.$showMenu) .frame(width: geometry.size.width, height: geometry.size.height) .offset(x: self.showMenu ? geometry.size.width/2 : 0) .disabled(self.showMenu ? true : false ) if self.showMenu { MenuView() .frame(width: geometry.size.width/2) .transition(.move(edge: .leading)) //slide in transition } } .gesture(drag) //swipe to the left the menu collapse } .navigationBarTitle( "Side Menu" , displayMode: . inline ) .navigationBarItems(leading: ( Button(action: { withAnimation { self.showMenu.toggle() } }) { Image(systemName: "line.horizontal.3" ) .imageScale(.large) } )) } // End Navigation } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } struct Home: View { @Binding var showMenu: Bool var body: some View { Button(action: { withAnimation { self.showMenu = true } print( "Open the side menu" ) }) { Text( "Show Menu" ) .padding() .background(Color.green) .foregroundColor(Color.white) .font(.title) } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | // // MenuView.swift // Test // // Created by Cairocoders // import SwiftUI struct MenuView: View { var body: some View { VStack(alignment: .leading) { HStack { Image(systemName: "person" ) .foregroundColor(.white) .imageScale(.large) Text( "Profile" ) .foregroundColor(.white) .font(.headline) } .padding(.top, 100) HStack { Image(systemName: "envelope" ) .foregroundColor(.white) .imageScale(.large) Text( "Messages" ) .foregroundColor(.white) .font(.headline) } .padding(.top, 30) HStack { Image(systemName: "gear" ) .foregroundColor(.white) .imageScale(.large) Text( "Settings" ) .foregroundColor(.white) .font(.headline) } .padding(.top, 30) HStack { Image(systemName: "figure.walk" ) .foregroundColor(.white) .imageScale(.large) Text( "Logout" ) .foregroundColor(.white) .font(.headline) } .padding(.top, 30) Spacer() } .padding() .frame(maxWidth: .infinity, alignment: .leading) .background(Color.gray) .edgesIgnoringSafeArea(.all) } } struct MenuView_Previews: PreviewProvider { static var previews: some View { MenuView() } } |