← 아카이브로 돌아가기

Development · SwiftUI

presentationDetents로 크기를 조절하는 Sheet 만들기

presentationDetents로 Sheet의 높이를 지정하고 selection으로 현재 크기를 제어하는 방법을 정리합니다.

Velog 원문 보기 ↗

Development 아카이브 표지

Sheet가 항상 화면 전체를 차지할 필요는 없다. 짧은 선택지는 작게 보여주고 필요한 순간에 확장할 수 있도록 presentationDetents의 높이와 현재 선택 값을 다뤄봤다.

presentationDetents

  • presentationDetents를 이용하여 원하는 크기로 sheet의 사이즈를 조정할 수 있다.
  • 사용자가 조정 가능한 사이즈의 범위를 set 형태로 지정한다.
  • 가능한 사이즈의 범위가 2개 이상일 경우 sheet 상단에 DragIndicator가 나타나는데, presentationDragIndicator를 이용해 제거할 수 있다.
  • 나타난 sheet는 Drag 및 Background Touch 등의 인터랙션으로 사라지게 할 수 있는데, interactiveDismissDisabled를 이용해 인터랙션을 비활성화할 수 있다.
struct SheetStudy: View {
    
    @State var showSheet: Bool = false
    
    var body: some View {
        
        Button("Click Me") {
            showSheet.toggle()
        }
        .sheet(isPresented: $showSheet) {
            ModalView()
                .presentationDetents([
                	.fraction(0.1), // 임의 비율
                    .height(300), // 임의 높이
                    .medium, // 중간 높이
                    .large // 전체 높이
                    ])
                // DragIndicatior 비활성화
                .presentationDragIndicator(.hidden)
                // 인터랙션 비활성화
                .interactiveDismissDisabled()
        }
        .onAppear {
            showSheet = true
        }
    }
}

Selection

selection 파라미터의 바인딩 값을 통해 사용자가 선택한 화면 높이를 추적한다. presentationDetents set 안에 있는 높이만 선택할 수 있기 때문에, 그 외의 값을 선택하면 높이 변화가 없다.

struct SheetStudy: View {
    
    @State var showSheet: Bool = false
    @State var detents: PresentationDetent = .medium
    
    var body: some View {
        
        Button("Click Me") {
            showSheet.toggle()
            detents = .large
        }
        .sheet(isPresented: $showSheet) {
            ModalView(detents: $detents)
            	// 높이 선택 값 바인딩
                .presentationDetents([.medium, .large], selection: $detents)
        }
        .onAppear {
            showSheet = true
        }
    }
    
}

struct ModalView: View {
    
    @Binding var detents: PresentationDetent
    
    var body: some View {
        ZStack {
            Color(.green).ignoresSafeArea()
            VStack {
                Button("medium") {
                    detents = .medium // 중간 높이 선택
                }
                Button("large") {
                    detents = .large // 전체 높이 선택
                }
            }
        }
    }
}

← 아카이브로 돌아가기