WWDC21:用可定制的 Sheet 改造模态窗口
发布
更新
字数
492
阅读
3 分钟
阅读量
1473
新的 UISheetPresentationController
类实现可定制的弹出层,所有样式可以使用实例属性修改。最简单的使用方法就是,获取之前弹出层控制器的 sheetPresentationController
属性并设置。
例如 present(viewController, animated: true)
变为
// Get a sheet
if let sheet = viewController.sheetPresentationController {
// Customizee the sheet
}
present(viewController, animated: true)
Detent
可以按比例控制弹出层高度,全屏高度或一半。
// Detents
if let sheet = picker.sheetPresentationController {
// `[.large()]` 只能全屏
// `[.medium()]` 只能半屏
// `[.medium(), .large()]` 默认半屏,可以手动拖拽切换
sheet.detents = [.medium(), .large()]
}
present(picker, animated: true)
示例
func showImagePicker() {
let picker = PHPickerViewController()
picker.delegate = self
// 1. Present at medium detent
if let sheet = picker.sheetPresentationController {
sheet.detents = [.medium(), .large()]
// 为了可以在 `.medium` detent 滚动内容,设置 `false` 阻止滚动到边缘时展开 sheet
sheet.prefersScrollingExpandsWhenScrolledToEdge = false
// 移除 `.medium` detent 时的暗色背景,允许同时交互
sheet.smallestUndimmedDetentIdentifier = .medium
// 如果需要,可以设置横屏时,不铺满屏幕
sheet.prefersEdgeAttachedInCompactHeight = true
sheet.widthFollowsPreferredContentSizeWhenEdgeAttached = true
// 拖拽显示条
sheet.prefersGrabberVisible = true
// 圆角
sheet.preferredCornerRadius = 24.0
}
present(picker, animated: true)
}
// MARK: - PHPickerViewControllerDelegate
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
// assign result to imageView.image
// ...
// 2. And don't dismiss automatically
// dismiss(animated: true)
// 3. 当选中一张图片时,保持 `.medium` detent
if let sheet = picker.sheetPresentationController {
// 5. 加入动画效果
sheet.animateChanges {
sheet.selectedDetentIdentifier = .medium
}
}
}
在 iPad 上,使用 popover 形式的弹出层:
func showImagePicker(_ sender: UIBarButtonItem) {
let picker = PHPickerViewController()
picker.delegate = self
// 设置弹层样式
picker.modalPresentationStyle = .popover
// 使用弹层 sheet
if let popover = picker.popoverPresentationController {
popover.barButtonItem = sender
// 自动响应布局,例如在分屏模式如果尺寸够窄(?)就会像手机上一样展示弹层
let sheet = popover.adaptiveSheetPresentationController
sheet.detents = [.medium(), .large()]
sheet.prefersScrollingExpandsWhenScrolledToedge = false
sheet.smallestUndimmedDetentIdentifier = .medium
}
present(picker, delegate: self)
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
// ...
// 同样要修改这里的 sheet
if let sheet = picker.popoverPresentationController?.adaptiveSheetPresentationController {
sheet.animateChanges {
sheet.selectedDetentIdentifier = .medium
}
}
}
_Via WWDC 2021: _Customize and resize sheets in UIKit