[SideMenuView.swift]

import SwiftUI

struct SideMenuView: View {
    @Binding var showMenu: Bool    
    var body: some View {
        
        VStack {
            // 우측상단 X 닫기 버튼
            HStack {
                Spacer()
                Button(action: {
                    showMenu.toggle()
                },
                label: {
                    Image(systemName: "xmark")
                        .font(.title3)
                        .foregroundColor(.black)
                })
            }
            .padding()
            
            // 타이틀 
            Text("Setting")
                .font(.title)
                .foregroundColor(.black)
            
            // 분리라인
            Divider()
                .frame(width: 200, height: 2)
                .background(Color.black)

            // 메뉴 버튼
            Link(destination: URL(string: "https://apple.com")!) {
                Text("Apple")
            }
            
            Spacer()
        }
        .padding(.top, 44)
        .frame(width: 300)
        .background(Color.gray)
        .edgesIgnoringSafeArea([.top, .bottom])
    }
}

#Preview {
    SideMenuView(showMenu: .constant(false))
}

 

[ContentView.swift]

import SwiftUI

struct ContentView: View {
    @State private var showMenu: Bool = false
    
    var body: some View {
        NavigationView {
            ZStack {
                // 백그라운드 배경색 
                Color.yellow.ignoresSafeArea(.all, edges: .all)
                
                VStack {
                    Text("ContentView")
                        .padding()
                        .font(.title)
                        .foregroundColor(.white)
                }
                
                // 사이드메뉴 표시 될때 백그라운드 배경
                if showMenu {
                    ZStack {
                        Color(.black)
                            .opacity(showMenu ? 0.25 : 0)
                            .onTapGesture {
                                withAnimation(.easeInOut) {
                                    showMenu = false
                                }
                            }
                    }
                    .ignoresSafeArea()
                }
                
                // 사이드메뉴
                GeometryReader { _ in
                    HStack {
                        SideMenuView(showMenu: $showMenu)
                            .navigationBarHidden(showMenu) // 네비게이션바 숨김(안숨기면 사이드메뉴 상단에 버튼 및 Text가 표시됨)
                            .offset(x: showMenu ? 0 : -UIScreen.main.bounds.width) // 좌측에서 -> 우측으로 표시 (- 빼면 우측 -> 좌측)
                            .animation(.easeInOut(duration: 0.3), value: showMenu)
                        Spacer()
                    }
                }
            }
            .navigationTitle("Side Menu Demo")
            .navigationBarTitleDisplayMode(.inline)
            
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button(action: {
                        self.showMenu.toggle()
                    },
                    label: {
                        Image(systemName: "text.justify")
                            .font(.title3)
                            .foregroundColor(.red)
                    })
                }
            }
        }
    }
}

#Preview {
    ContentView()
}

+ Recent posts