티스토리 뷰

WWDC2021에서 나온 UISheetPresentationController에 대해 알아보자.

 

공식 문서의 예제와 영상을 보고 공부해 보았다.

 

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

 

Get Sheet

먼저 ViewController를 Navigation Controller에 Embed 하고 BarButtonItem을 추가해 주었다.

import UIKit
import PhotosUI // PHPickerViewController

class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate, PHPickerViewControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "Custom Sheet"
        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(showImagePicker))
    }
}

 

UISheetPresentationController를 이용해 Sheet를 만들고 크기를 조정할 수 있다. 

먼저 Sheet를 생성해보자.

@objc
func showImagePicker() {
    var configuration = PHPickerConfiguration()
    let picker = PHPickerViewController(configuration: configuration)
    picker.delegate = self
    
    // Get a sheet
    if let sheet = picker.sheetPresentationController {
        //Customize the sheet
    }
    present(picker, animated: true)
}

// Image를 선택을 마치면 호출
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    //dismiss(animated: true)
}

viewController의 sheetPresentationController라는 프로퍼티를 통해 sheet을 생성했다.

(예제에서는 PHPickerViewController를 sheet로 보여주는데 다른 viewController도 물론 가능하다.)

 

이상태로 실행해서 버튼을 눌러보면 

Sheet가 올라온다!

 

이제 Sheet의 동작과 모양을 커스텀해보자.

 

Detents

Detent는 sheet가 놓일 수 있는 높이의 배열이다.

.medium
.large

기본값으로. large만 설정되어있다.

 

sheet의 detents 배열에 medium을 추가해 보았다.

if let sheet = picker.sheetPresentationController {
    //Customize the sheet
    sheet.detents = [
        .medium(),
        .large()
    ]
}

 

 

iOS16부터는 Custom Detent를 만들어 원하는 높이의 Sheet를 사용할 수 있다.

iOS) UISheetPresentationController - Custom Detents로 Sheet 높이 설정하기(WWDC2022)

 

prefersScrollingExpandsWhenScrolledToEdge

그런데 PHPickerViewController에 선택 가능한 이미지가 많을 경우에 스크롤을 해야 한다. 

하지만 위의 화면처럼 아래에서 위로 스크롤을 하면 Sheet의 Detent가 large로 바뀌어 버린다. 

이때 prefersScrollingExpandsWhenScrolledToEdge 프로퍼티를 false로 설정해 주면 스크롤 시 sheet가 확장되는 것을 막아준다.

sheet.prefersScrollingExpandsWhenScrolledToEdge = false

 

이 프로퍼티의 기본값은 true로 이때 가장 큰 detent에 도달해야만 sheet 내부 스크롤이 가능하자.

 

selectedDetentIdentifier

selectedDetentIdentifier를 코드로 직접 호출해 detent를 변경해줄 수 있다.

 

아래 코드는 PHPicker에서 이미지를 선택했을 때 detent를 medium으로 변경해준다.

// 이미지 선택을 종료했을때 호출
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    if let sheet = picker.sheetPresentationController {
        sheet.selectedDetentIdentifier = .medium // detent 변경
    }
}

 

animateChanges

animation을 추가해 부드럽게 바꿔줄 수도 있다.

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    if let sheet = picker.sheetPresentationController {
        sheet.animateChanges {
            sheet.selectedDetentIdentifier = .medium
        }
    }
}

 

 

largestUndimmedDetentIdentifier

지금까지 실행 화면들을 보면 sheet가 나올 때 뒤의 View가 어둡게(dim) 변한다.

largestUndimmedDetentIdentifier 프로퍼티를 이용해 뒤의 view를 어둡지 않게 하는 최대 Detent를 설정할 수 있다.

sheet.largestUndimmedDetentIdentifier = .medium

 

 

 

위의 프로퍼티들 외에도

Sheet 상단에 Grabber를 보이는 prefersGrabberVisible, Sheet에 CornerRadius를 주는 preferredCornerRadius 등이 있다.

 

Delegate

UISheetPresentationController는 UIPresentationController를 상속받고 있어 UIPresentationControllerDelegate 메서드도 사용 가능하다.

// Sheet의 Detent가 바뀌면 호출
func sheetPresentationControllerDidChangeSelectedDetentIdentifier(_ sheetPresentationController: UISheetPresentationController) {
    print("sheetPresentationControllerDidChangeSelectedDetentIdentifier")
}

// UIPresentationController
// Sheet가 dismiss될때 호출
func presentationControllerWillDismiss(_ presentationController: UIPresentationController) {
    print("PresentationControllerWillDismiss")
    self.view.backgroundColor = .white
}

 

 

이렇게 sheetPresentationController에 대해서 정리해 보았다. 직접 프로젝트에 적용시켜 보면서 더 공부해 봐야겠다.

그리고 WWDC22에서 나온 내용들 얼른 공부해봐야지 ㅠ

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함