개발 창고/iOS

[SwiftUI] How to Go to the Previous View (Go Back)

로이제로 2023. 12. 22. 22:00
반응형

1. 화면 이동 소스

 일반적으로 SwiftUI에서는 NavigationView나 NavigationStack 등을 이용하면 아래와 같이 Navigation의 '뒤로가기' 버튼이 자동 활성됩니다.

import SwiftUI

// View 페이지
struct TestView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: TestView02()){
                Text("TestView02로 이동")
            }
        }
    }
}

// View 페이지 (다음 페이지)
struct TestView02: View {
    var body: some View {
        Text("여기는 TestView02 페이지입니다.")
    }
}

// View 미리보기
struct TestView_Previews: PreviewProvider {
    static var previews: some View {
        TestView()
    }
}

2. 실행 결과

 만약 위와 같이 TestView에서 TestView02로 이동하는 두 개의 View가 있다고 가정하고 Preview에서 TestView를 실행해주면 아래와 같은 화면이 보이게 됩니다.

TestView02로 이동하는 버튼이 있는 TestView01 화면

 여기서 "TestView02로 이동"을 클릭 해 주면 화면은 TestView에서 TestView02로 이동하며 상단에 Navigation영역이 활성된 것을 확인할 수 있습니다.

TestView01에서 이동한 TestView02 화면

 여기서 "Back" 버튼을 클릭 하면 화면은 TestView02에서 TestView로 돌아가게 됩니다.

 그런데, 만약 "여기는 TestView02 페이지입니다." 밑에 "취소" 버튼을 만들고 클릭하면 Back처럼 뒤로 가려면 어떻게 해야 할까요? (일반적인 사용 방법은 "취소" 보다는 저장이나 선택 등 이후 다시 이전 페이지로 돌아가는 데 사용될 것입니다.)


3. dismiss 적용 소스

 TestView02를 아래와 같이 수정해 주면 원하는 결과를 얻을 수 있습니다.

struct TestView02: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    
    var body: some View {
        VStack {
            Text("여기는 TestView02 페이지입니다.")
            
            Button(action:{ self.presentationMode.wrappedValue.dismiss() }){
                Text("취소")
            }
        }
    }
}

 환경 변수인 presentationMode를 받아온 후, "취소" Button을 클릭했을 때 action 에서 wrappedValue를 dismiss()해주면, 현재 페이지가 만료됩니다.

취소"라는 dismiss를 하기위한 버튼이 추가된 TestView02 화면


4. iOS15 이후 dismiss

iOS15 이후 부터는 dismiss를 환경변수에서 받아와 선언도 가능합니다.

struct TestView02: View {
    // @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        VStack {
            Text("여기는 TestView02 페이지입니다.")
            
            // Button(action:{ self.presentationMode.wrappedValue.dismiss() }){
            Button(action:{ dismiss() }){
                Text("취소")
            }
        }
    }
}
반응형