본문 바로가기
이모저모/UIKit

WWDC) Customize and resize sheets in UIKit

by ARpple 2023. 8. 2.

iOS 15이상에 적용 가능한 UIKit Sheet 조작

 

 

Customize and resize sheets in UIKit - WWDC21 - Videos - Apple Developer

Discover how you can create a layered and customized sheet experience in UIKit. We'll explore how you can build a non-modal experience in...

developer.apple.com

💡 UIKit에서 계층화된 맞춤형 Sheet를 만드는 방법 앱에서 Default 모달을 벗어난 시트 안과 시트 뒤의 콘텐츠와 동시에 상호 작용을 해보자
+ 시트 크기 사용자 지정, 그래버 컨트롤 표시 또는 숨기기, 앱에서 팝오버와 사용자 지정 시트 간에 조정하는 방법도 알아보자

참고자료

WWDC19에서 "iOS 13의 UI Mordernizing"

 

Modernizing Your UI for iOS 13 - WWDC19 - Videos - Apple Developer

iOS 13 combines powerful new multitasking and productivity technologies with a refreshed look and feel for all applications. Familiarize...

developer.apple.com

UISheetPresentationController

 

UISheetPresentationController | Apple Developer Documentation

A presentation controller that manages the appearance and behavior of a sheet.

developer.apple.com

UIPresentationContoller의 하위 클래스

여기에서 UISheetPresentationController 인스턴스를 가져올 수 있다.

if let sheet = viewController.sheetPresentationController {
    // Customize the sheet
}
present(viewController, animated: true)

Detents

What are detents?

💡 detent는 시트가 자연스럽게 놓이는 높이, 완전히 펼친 시트 프레임의 일부분으로 정의함
 완전히 펼쳐진 프레임은 iPhone과 iPad에서 시각화되어 있음
 iOS 15는 시트 전체 높이의 절반 정도인 Medium Detent, 완전히 확장된 시트의 높이인 Large Detent 두 가지 타입을 제공
 - 물론 커스텀 높이 Detent를 만들 수도 있음

아이패드와 아이폰 Detent가 표시되는 영역 (파란색 점선)

if let sheet = picker.sheetPresentationController {
    sheet.detents = [.medium(), .large()]
}
present(picker, animated: true)

시트 내부 뷰 스크롤을 하면 확장되는 효과를 없애기

sheet.prefersScrollingExpandsWhenScrolledToEdge = false
  • 이 코드를 실행하면 뷰 내부의 스크롤로 인해 detents가 확장되는 것을 막을 수 있다.
  • but, navigation bar 영역을 스크롤 하면 detents가 확장됨

시트의 detent를 코드로 지정하기

sheet.selectedDetentIdentifier = .medium

Dimming

💡 Dimming은 시트를 올리면 뒷 뷰를 그림자 영역처리하는 것을 의미한다. 뒷 뷰와 상호작용을 막는 기능을 갖고 있다.
 기본적인 Modal은 이 dimming 처리를 기본으로 구성한다.

Dimming 처리 없애기

let customIdentifer: UISheetPresentationController.Detent.Identifier 
                                                                                                = customDetent.identifier
sheet.largestUndimmedDetentIdentifier = customIdentifer
//sheet.largestUndimmedDetentIdentifier = .medium
⚠️ 내부적으로 WWDC 영상과 코드가 프로퍼티가 바뀐 것 같다..!
  • UISheetPresentationController.Detent.Identifier → 구조체를 설정한다.
    1. 커스텀 detent는 .identifer 프로퍼티를 통해 인스턴스를 할당하면 된다.
    2. 시스템에서 제공하는 detent 타입 medium, large를 위한 값이 있다.
  • .largestUndimmedDetentIdentifier의 의미위에 코드를 실행하면 높이가 70정도인 커스텀 영역까지는 dimming이 적용 되지 않았지만, medium이 되니 dimming이 적용되었다.
    1. Medium detent에서 앨범 이미지를 변경해 뒷 뷰에 적용되는 것을 볼 수는 있지만, 뒷 뷰와 Interaction을 할 순 없다.
    2. 이 detentIdentifier 까지 Undimmed로 설정할 것이다라는 의미이다.

시트 디자인

Detent 크기 변화시 Fade 애니메이션 주기

 

// 이 클로져 내부에서 로직을 구성하면 된다
sheet.animateChanges {
    sheet.selectedDetentIdentifier = .medium
}

 

 

 

 


Compact 유형 설정하기

if let sheet = fontPicker.sheetPresentationController {
        // 시트를 compact기준으로 줄임
    sheet.prefersEdgeAttachedInCompactHeight = true
        // 좌,우 여백을 콘텐츠 너비만큼 줄임
    sheet.widthFollowsPreferredContentSizeWhenEdgeAttached = true
    sheet.prefersGrabberVisible = true // 그랩 이미지 보여주기
    sheet.preferredCornerRadius = 20.0 // 시트의 코너 둥글게 만들기
}

이게 Grab!!

팝 오버 뷰 대응하기

팝 오버 뷰는 iPad에서 보여지는 팝업을 통한 시트가 나타나는 뷰이다.
주로 아이패드 공유하기 버튼을 누르면 나타남
func showImagePicker(_ sender: UIBarButtonItem) {
    let picker = PHPickerViewController()
    picker.delegate = self
    picker.modalPresentationStyle = .popover
    if let popover = picker.popoverPresentationController {
        popover.barButtonItem = sender
        let sheet = popover.adaptiveSheetPresentationController
        sheet.detents = [.medium(), .large()]
        sheet.prefersScrollingExpandsWhenScrolledToEdge = false
        sheet.smallestUndimmedDetentIdentifier = .medium
    }
    present(picker, animated: true)
}

소스 코드 프로젝트

Detent_ios15.zip
0.07MB

댓글