๐ŸŽ iOS & Swift

[WWDC21] SheetViewController (Session. Customize and resize sheets in UIKit)

taeeekki 2022. 8. 2. 20:49

iOS 15์—์„œ๋Š” Sheet์— ์—ฌ๋Ÿฌ ์ปค์Šคํ…€ ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ex. ํ™”๋ฉด์˜ ์ ˆ๋ฐ˜ ํฌ๊ธฐ๋กœ ์‹œํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ex. Dimmed View๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ex. ์‹œํŠธ ์•ˆ๊ณผ ์‹œํŠธ ๋’ค์—์„œ ๋™์‹œ์— ์ฝ˜ํ…์ธ ์™€ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์•ฑ์—์„œ ๋น„๋ชจ๋‹ฌ ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1. Getting a sheet

Sheet ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. UIPresentationController์˜ ์„œ๋ธŒ ํด๋ž˜์Šค์ธ UISheetPresentationController๋ฅผ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค. ์‹œํŠธ๋กœ ๋„์šฐ๊ณ  ์‹ถ์€ ์ธ์Šคํ„ด์Šค์— sheetPresentationController๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

let viewControllerToPresent = UIViewController()
if let sheet = viewControllerToPresent.sheetPresentationController {
  // customize
}
present(viewController, animated: true)

2. detents

  • ์‹œํŠธ๊ฐ€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋†“์ด๋Š” ๋†’์ด
  • ์™„์ „ํžˆ ํ™•์žฅ๋œ ์‹œํŠธ ํ”„๋ ˆ์ž„์˜ ์ผ๋ถ€

2๊ฐ€์ง€์˜ detents๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

  • ์ „์ฒด ๋†’์ด์˜ ์•ฝ ์ ˆ๋ฐ˜์ธ ์ค‘๊ฐ„ detent
  • ์™„์ „ํžˆ ํ™•์žฅ๋œ ์‹œํŠธ์˜ ๋†’์ด์ธ ํฐ detent

Array๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

sheet.detents = [.large()]
sheet.detents = [.medium(), .large()] // resizable ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
sheet.detents = [.medium()] // full height์œผ๋กœ resizable ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


What’s new in UIKit์„ ์ฐธ๊ณ ํ•˜์ž.

iOS 16๋ถ€ํ„ฐ๋Š” ๋†’์ด๋ฅผ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

if let sheet = viewController.sheetPresentationController {
    sheet.detents = [
        .custom { _ in
            return 200
        }
    ]
}
if let sheet = viewController.sheetPresentationController {
    sheet.detents = [
        .custom { _ in
            return 200
        },
        .custom { context in
            return context.maximumDetentValue * 0.6
        }
    ]
}

3. PickerViewController์— ์ ์šฉํ•˜๊ธฐ

Present image picker in a standard sheet

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

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
	dismiss(animated: true)
}

4. prefersScrollingExpandWhenScrolledToEdge

  • ์Šคํฌ๋กค์ด ์ค‘์ฒฉ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ์—์„œ ๋™์ž‘์„ ์›ํ•˜๋Š”๋Œ€๋กœ ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • default๋Š” True์ž…๋‹ˆ๋‹ค.

๋‚ด๋ถ€ ์ปจํ…์ธ ๋ฅผ ์Šคํฌ๋กคํ•˜๋ฉด ๊ฐ™์ด ๋”ฐ๋ผ์˜ฌ๋ผ๊ฐ€๋Š” ๋ฌธ์ œ


5-1. Dimmed View ์ œ๊ฑฐ

largestUndimmedDetentIdentifier

์‹œํŠธ ์•ˆ๊ณผ ์‹œํŠธ ๋’ค์—์„œ ๋™์‹œ์— ์ฝ˜ํ…์ธ ์™€ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์•ฑ์—์„œ ๋น„๋ชจ๋‹ฌ ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

sheet.largestUndimmedDetentIdentifier = .medium  // Defualt: nil
  • ์ง€์ •ํ•œ detent๋ณด๋‹ค ํฐ detent์—๋งŒ dimmed view๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

5-2. delegate์™€ ์—ฎ๊ธฐ

dimmed view๋ฅผ ์ œ๊ฑฐํ•˜๊ณ , delegate๋ฅผ ์ด์šฉํ•˜๋ฉด ์ปค์Šคํ„ฐ๋งˆ์ด์ฆˆํ•œ ์ƒํ˜ธ ์ž‘์šฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.


6. ๊ฐ€๋กœ๋ชจ๋“œ ์‹œ

sheet.prefersEdgeAttachedInCompactHeight = true


7. Grabber

sheet.prefersGrabberVisible = true


8. CornerRadius

sheet.preferredCornerRadius = 20


9. Adaptation from popover

iPad์—์„œ ์‹œํŠธ ๋Œ€์‹  ํŒ์˜ค๋ฒ„๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” modal์˜ presentation style์„ popover๋กœ ์„ค์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  sheetPresentationController ๋Œ€์‹  popoverPresentationController์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.


GitHub ์›๋ณธ ์ถœ์ฒ˜

https://github.com/Secret-Of-SwiftUI/SSDC22/issues/21