SwiftUI에서 옆에서 등장하면서 화면을 반만가리고,
뒷배경은 조금 어둡게 하는 기능을 구현해야했다.
위 뷰를 뭐라고하는지 따로 정의가 되어있지 않아서,
그냥 나는 사이드 뷰 또는 슬라이드 뷰라고 부르겠다.

위와 같은 느낌이다.
기본적으로 ZStack을 기반으로한다.
- 메뉴콘텐츠 만들기
struct MenuContent: View {
var body: some View {
List {
Text("My Profile").onTapGesture {
print("My Profile")
}
Text("Posts").onTapGesture {
print("Posts")
}
Text("Logout").onTapGesture {
print("Logout")
}
}
}
}
- 사이드 메뉴 만들기
struct SideMenu: View {
let width: CGFloat
let isOpen: Bool
let menuClose: () -> Void
var body: some View {
// Code here
}
}
- 배경 뷰 만들기
struct SideMenu: View {
let width: CGFloat
let isOpen: Bool
let menuClose: () -> Void
var body: some View {
ZStack {
// Code here
}
}
}
- 애니메이션 추가 뒷배경 추가
GeometryReader { _ in
EmptyView()
}
.background(Color.gray.opacity(0.3))
.opacity(self.isOpen ? 1.0 : 0.0)
.animation(Animation.easeIn.delay(0.25))
.onTapGesture {
self.menuClose()
}
- 메뉴 컨텐츠 추가하기
HStack {
MenuContent()
.frame(width: self.width)
.background(Color.white)
.offset(x: self.isOpen ? 0 : -self.width)
.animation(.default)
Spacer()
}
- ContentView에 메뉴 및 열기 버튼 추가
struct ContentView: View {
@State var menuOpen: Bool = false
var body: some View {
// Code here
}
func openMenu() {
self.menuOpen.toggle()
}
}
ZStack {
if !self.menuOpen {
Button(action: {
self.openMenu()
}, label: {
Text("Open")
})
}
SideMenu(width: 270,
isOpen: self.menuOpen,
menuClose: self.openMenu)
}
최종코드
import SwiftUI
struct MenuContent: View {
var body: some View {
List {
Text("My Profile").onTapGesture {
print("My Profile")
}
Text("Posts").onTapGesture {
print("Posts")
}
Text("Logout").onTapGesture {
print("Logout")
}
}
}
}
struct SideMenu: View {
let width: CGFloat
let isOpen: Bool
let menuClose: () -> Void
var body: some View {
ZStack {
GeometryReader { _ in
EmptyView()
}
.background(Color.gray.opacity(0.3))
.opacity(self.isOpen ? 1.0 : 0.0)
.animation(Animation.easeIn.delay(0.25))
.onTapGesture {
self.menuClose()
}
HStack {
MenuContent()
.frame(width: self.width)
.background(Color.white)
.offset(x: self.isOpen ? 0 : -self.width)
.animation(.default)
Spacer()
}
}
}
}
struct ContentView: View {
@State var menuOpen: Bool = false
var body: some View {
ZStack {
if !self.menuOpen {
Button(action: {
self.openMenu()
}, label: {
Text("Open")
})
}
SideMenu(width: 270,
isOpen: self.menuOpen,
menuClose: self.openMenu)
}
}
func openMenu() {
self.menuOpen.toggle()
}
}
간단한 예제로 구현해보았다.