SwiftUI_Slideoutmenu
This is a sample code project for a slideout menu.
Simulator.Screen.Recording.-.iPhone.13.-.2022-02-13.at.09.48.29.mp4
How to Implement
- Copy over the Model, Views, & HelperViews files to your project.
- Add
SlideOutMenuView(showMenu: $showMenu)
to your mainview within aZStack
as anif
statement.
Example:
if showMenu {
SlideOutMenuView(showMenu: $showMenu)
.shadow(color: Color("nord2").opacity(0.5), radius: 5, x: 0, y: 0)
.transition(.opacity)
.animation(.easeInOut, value: showMenu)
}
- Add the
AnimationModifier
andoffset
to your view.
Example:
VStack {
YourView()
}
.modifier(AnimationModifier(showMenu: $showMenu, animationAmount: $animationAmount))
.offset(x: offset.width)
Getting Started Code
VStack {
YourView()
}
.modifier(AnimationModifier(showMenu: $showMenu, animationAmount: $animationAmount))
.onTapGesture {
withAnimation {
showMenu.toggle()
}
}
.offset(x: offset.width)
.disabled(showMenu ? true : false)
if showMenu {
SlideOutMenuView(showMenu: $showMenu)
.shadow(color: Color("nord2").opacity(0.5), radius: 5, x: 0, y: 0)
.transition(.opacity)
.animation(.easeInOut, value: showMenu)
}
Updating the Menu
- Update
MenuItems
with your content - Update the
switch
statement withinSlideOutMenuView.swift
Example:
.onTapGesture {
switch item.id {
case 0:
showSomeSheet1 = true
case 1:
showSomeSheet2 = true
default:
showSomeSheet3 = true
}
}
- Add the neccesary sheets needed. There is a starter sheet located within
SlideOutMenuView.swift
.
Calling the Slideout Menu
You can call the menu by utilzing a Bool
State, in the code example I used showMenu
and is triggered by swipping and a toolbar
button.
Code Examples
Button:
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button(action: {
withAnimation(.spring()) {
showMenu = true
}
}) {
Image(systemName: "gearshape.fill")
}
}
}
Swipe Gesture:
.gesture(DragGesture()
.onChanged { gesture in
// increase startLocation to increase edge detection
if gesture.startLocation.x < CGFloat(50.0) {
withAnimation {
offset = gesture.translation
}
}
}.onEnded{ value in
if offset.width > 115 {
withAnimation(.spring()) {
showMenu = true
offset = .zero
}
} else {
withAnimation(.spring()) {
offset = .zero
}
}
})
Customizing
Menu Options
MenuItemModel
contains the slideout menu options. You could create another model
for additonal options near the the top of the menu.
Animation Modifier
I created a custom modifier AnimationModifier
to reduce code. This has the bulk of the 3d modifiers to animate the view in ContentView
.
Gesture Control
To increase or decrease edge detection update if gesture.startLocation.x < CGFloat(50.0)
. If you want to adjust how much a user needs to swipe you'll need to adjust if offset.width > 115
in ContentView.swift
Presenting Sheets
The sheets are located inwithin SlideOutMenuView.swift
and I have added one sheet as an example. You could also swap out a sheet for a fullScreenCover
.
Menu Size
Within SlideOutMenuView.swift
you can update the frame size located at .frame(width: geo.size.width / 1.75)
.
Other Notes
There is a .disabled
modifier to disable ContentView
when the menu appears otherwise the user could experience some weird behaviors if ContentView
is still active.
Feel free to email me with any questions [email protected]