-
SwiftUI) Binding, presentationMode (Two ways to dismiss view)SwiftUI/Basic Property Wrappers 2021. 9. 13. 14:10
어떤 프로젝트를 보다가,
다음과 같은 코드를 보고 열심히 찾아보았다.
@Environment(\.presentationMode) var presentationMode
결론부터 말하면, SwiftUI 에서 sheet 를 이용할 때 dismiss 하는 방법 중 하나로 많이 쓰이는 방법이고,
보통 두가지 방법이 쓰인다. ( presentationMode, Binding )
1. presentationMode 이용하기.
해당 sheet 에서 'presentation mode environment key' 를 이용하여 스스로를 dismiss 하라고 시키는 방법이다.
어떠한 view 에서도 presentation mode 를 @Environment(\.presentationMode) 를 이용해 읽을 수 있고,
wrappedValue.dismiss() 를 call 함으로 dismiss 시킬 수 있다.
@Environment(\.presentationMode) var presentationMode
presentationMode.wrappedValue.dismiss()
아래는 예제 코드이다.
struct ContentView: View { @State private var showingDetail = false var body: some View { Button("Show Detail") { showingDetail = true } .sheet(isPresented: $showingDetail) { DetailView1() } } } struct DetailView1: View { @Environment(\.presentationMode) var presentationMode var body: some View { Button("Dismiss Me") { presentationMode.wrappedValue.dismiss() } } }
ContentView 에서 버튼을 누를 때 showingDetail 를 true 값으로 바꾸고,
그에 따라 DetailView1() 를 sheet 로 present 한다.
DetailView1 에서는 "Dismiss Me" 라고 써있는 버튼을 누르면
presentationMode.wrappedValue.dismiss() 가 호출되며,
이에 따라 해당 뷰가 dismiss (사라지게) 된다.
(꼭 variable name을 presentationMode 라고 할 필요는 없으나, 관례인듯 하다.)
@State private var showingDetail = false
다른 view 를 present 할 때 많이 쓰이는 방식이다.
2. Binding 이용하기
DetailView2 에 binding 을 넘기는 방식으로, DetailView2 에서 해당 값을 false 로 바꿔줄 때
그 뷰를 dismiss 시킨다.
이 경우 presenting view (ContentView) 에 @State variable (showingDetail) 을 선언해주어야한다.
struct ContentView: View { @State private var showingDetail = false var body: some View { Button("Show Detail") { showingDetail = true } .sheet(isPresented: $showingDetail) { DetailView2(isPresented: $showingDetail) } } } struct DetailView2: View { @Binding var isPresented: Bool var body: some View { Button("Dismiss Me") { isPresented = false } } }
1.ContentView 에서 버튼을 누르면 binding 시킬 variable (showingDetail) 을 DetailView2 로 pass ! -->> DetailView2 는 isPresented 값으로 받음. (두 변수가 서로 연결, 즉 항상 같은 값을 갖게 됨)
2. DissmissingView2 에서 해당 binding 된 값 (@State isPresented) 을 false 로 변환시킬 수 있음 . (변환시 dismiss!)
두 Views, 즉 DetailView2 와 ContentView 에서 같은 boolean value 를 가리키므로 (showDetail === isPresented) 어느 View 에서나 해당 값을 바꾸면 다른 view 에서도 바로 적용됨.
3. 따라서 DetailView2 에서 버튼 클릭 -> isPresented = false 로 toggle, showingDetail 도 false 로 toggle, ContentView 에서 sheet 가 present 되는 조건은 showingDetail 이 true 일 때 이므로, 해당 조건을 만족시키지 않아 DetailView2 를 dismiss 시킴.
(참고로, showingDetail 을 true 로 처음에 선언하게 되면 ContentView 가 출현함과 동시에 sheet (DetailView2) 가 나타난다.)
해당 source 를 참조하였습니다.
https://www.hackingwithswift.com/quick-start/swiftui/how-to-make-a-view-dismiss-itself
'SwiftUI > Basic Property Wrappers' 카테고리의 다른 글
PassthroughSubject VS CurrentValueSubject (0) 2021.12.10 SwiftUI ) StateObject, EnvironmentObject, ObservedObject2 (1) 2021.10.06 SwiftUI ) StateObject Apple Documentation 번역 (0) 2021.10.05 SwiftUI) State, ObservedObject, StateObject, and EnvironmentObject (0) 2021.09.13 SwiftUI) State, Binding wrapper (0) 2021.09.13