sheet
SwiftUI에서 sheet은 UIKit에서 modal과 유사하게 모달뷰를 표시하는데 사용한다.
유저가 모달뷰를 닫기 전까지 기존 뷰를 덮고, 새로운 뷰를 표시한다.
바인딩 변수를 전달해야 하고, content 클로저에서 조건문을 사용하면 안 되는 점을 주의하자.
why?
*시트를 통한 뷰는 부모뷰가 생성될 때 같이 생성된다.
먼저 코드의 가독성과 유지보수성 측면에서 단점이 있다.
sheet content 클로저 내부에서 조건문을 사용해 다양한 뷰를 표시하려면 코드가 복잡해지고,
중복되는 코드가 발생할 가능성이 있으며 이는 가독성과 유지보수를 어렵게 만든다.
-> 각 뷰를 별도의 변수로 추출해서 뷰의 계층 구조를 간결하게 유지하는 방향이 좋다.
다양한 뷰를 띄우는 방식은 다음에 더 자세히 알아보도록 하자.
또한 sheet는 뷰당 한 번만 사용 가능하다.
.sheet(...)
.sheet(...)과 같은 형태는 불가능하다는 의미. (.fullScreenCover도 마찬가지)
또한 모달뷰는 드래그 제스쳐를 통해(아래로 내리는 동작) 사라지게(dismiss)할 수 있는데 (fullScreenCover는 불가능)
이를 위해서는 프로퍼티 래퍼중 하나인 @Environment를 알아야 한다.
@Environment
Swift에서 property wrapper는 특별한 기능을 제공하도록 구현된 구조체나 클래스이다.
다른 속성을 래핑하고, 그 속성에 '추가적인 기능을 부여'한다.
@Environment는 뷰 계층 구조 (View Hierarchy)에서 환경 값을 캡슐화하는 데 사용된다.
이는 뷰 계층 구조에서 공유되는 값을 저장하고 전달하는데 유용하며, 이를 통해서
뷰 계층 구조에서 일관성 있는 동작을 보장하고 뷰 간의 결합도를 낮출 수도 있다.
예시를 통해 sheet, fullscreencover, @Environment에 대해 알아보자.
// Created by Toughie on 2023/04/24.
//
import SwiftUI
struct Sheets: View {
//sheet의 바인딩 파라미터에 전달할 @State 변수
@State var showSheet: Bool = false
var body: some View {
ZStack {
Color.blue.opacity(0.5)
.ignoresSafeArea()
Button {
//버튼을 통해 토글
showSheet.toggle()
} label: {
Text("Button")
.foregroundColor(.blue)
.font(.headline)
.padding(20)
.background(Color.white.cornerRadius(10))
}
//뷰당 한 번만 사용 가능 (.sheet()여러번 불가능!)
//클로저 안에서 조건문 사용 금지(지양)
//분기 처리를 통해 여러 뷰를 띄우려고 하면 안 됨.(다른 방법이 있음)
//시트는 속해있는 뷰가 생성될 때 같이 생성되기 때문에
.sheet(isPresented: $showSheet) {
SecondView()
}
//fullScreenCover도 sheet와 거의 동일. 다만 제스쳐를 통한 dismiss 불가
// .fullScreenCover(isPresented: $showSheet) {
// SecondView()
// }
}
}
}
struct SecondView: View {
//to dismiss sheet
/*
시트를 사라지게 하기 위해 필요
자동완성이 안 되기 때문에 암기하는 것이 좋음.
변수명은 다르게 지을 수도 있음.
*/
@Environment(\.presentationMode) var presentationMode
var body: some View {
ZStack(alignment: .topLeading) {
Color.green.opacity(0.5)
.ignoresSafeArea()
Button {
//뷰 계층 구조에서 정의된 환경 변수에 접근하기 .dissmiss() 호출
presentationMode.wrappedValue.dismiss()
} label: {
Image(systemName: "xmark")
.foregroundColor(.green)
.font(.headline)
.padding(10)
.background(Color.white.cornerRadius(10))
.padding(20)
}
}
}
}
fullScreenCover는 위에서 언급했듯이 sheet와 거의 유사하지만
화면을 꽉 채우고, 제스처를 통한 dismiss가 불가능하다는 차이가 있다.
(새로운 뷰를 띄운다는 점은 동일하다.)
+ 모달뷰에 관해서
-모달뷰는 언제 사용하면 좋은가?
시트(모달)는 아래와 같은 상황에서 사용될 수 있다.
1. 추가적인 정보를 요구하는 경우
- 유저에게 선택 사항이나 추가 정보를 제공할 때 (어떤 작업 수행 중에 추가 정보가 필요한 경우 모달 뷰를 통해 추가 정보 제공 가능)
2. 액션 수행 전 경고 표시용
- 중요한 작업 시작 전에 경고가 필요한 경우
3. 피드백 제공
- 작업이 완료되었다는 피드백, 실패했을 경우 실패한 이유를 알릴 때(알럿도 자주 쓰임)
4. 작업 용도(완료용)
- 새로운 항목을 추가하거나 설정을 변경하거나 다른 사용자와 공유하기 위한 콘텐츠 생성 등의 작업 수행 시 사용 가능
5.광고 표시용
모달뷰는 일시적인 뷰이고, 사용자는 모달뷰를 닫을 수 있기 때문에(제스처를 통해) 해당 특징을 잘 파악해서 사용하는 것이 중요하겠다.
'SwiftUI > SwiftUI(Basic)' 카테고리의 다른 글
28. [SwiftUI] NavigationView, NavigationLink (0) | 2023.04.27 |
---|---|
27. [SwiftUI] Popover Views (sheet, transition, offset) .zIndex(), px/pt (0) | 2023.04.27 |
25. [SwiftUI] Transition (0) | 2023.04.23 |
24. [SwiftUI] Animation Curves and Timing (0) | 2023.04.23 |
23. [SwiftUI] Animations basic (0) | 2023.04.23 |