ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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

Designed by Tistory.