Use SwiftUI for sheet presentation detents on iOS 16

This commit is contained in:
Shadowfacts 2022-06-28 17:27:41 -07:00
parent 10f6a68065
commit c6e06fe9f3
2 changed files with 50 additions and 2 deletions

View File

@ -50,7 +50,7 @@ struct ComposeAttachmentsList: View {
.disabled(!canAddAttachment) .disabled(!canAddAttachment)
.foregroundColor(.blue) .foregroundColor(.blue)
.frame(height: cellHeight / 2) .frame(height: cellHeight / 2)
.popover(isPresented: $isShowingAssetPickerPopover, content: self.assetPickerPopover) .sheetOrPopover(isPresented: $isShowingAssetPickerPopover, content: self.assetPickerPopover)
.listRowInsets(EdgeInsets(top: cellPadding / 2, leading: cellPadding / 2, bottom: cellPadding / 2, trailing: cellPadding / 2)) .listRowInsets(EdgeInsets(top: cellPadding / 2, leading: cellPadding / 2, bottom: cellPadding / 2, trailing: cellPadding / 2))
Button(action: self.createDrawing) { Button(action: self.createDrawing) {
@ -134,14 +134,21 @@ struct ComposeAttachmentsList: View {
private func assetPickerPopover() -> some View { private func assetPickerPopover() -> some View {
ComposeAssetPicker(draft: draft, delegate: uiState.delegate?.assetPickerDelegate) ComposeAssetPicker(draft: draft, delegate: uiState.delegate?.assetPickerDelegate)
.onDisappear { .onDisappear {
// on iPadOS 16, this is necessary to dismiss the popover when collapsing from regular -> compact size class
// otherwise, the popover isn't visible but it's still "presented", so the sheet can't be shown
self.isShowingAssetPickerPopover = false self.isShowingAssetPickerPopover = false
} }
// on iPadOS 16, this is necessary to show the dark color in the popover arrow
.background(Color(.systemBackground))
.environment(\.colorScheme, .dark) .environment(\.colorScheme, .dark)
.edgesIgnoringSafeArea(.bottom) .edgesIgnoringSafeArea(.bottom)
.withSheetDetentsIfAvailable()
} }
private func addAttachment() { private func addAttachment() {
if horizontalSizeClass == .regular { if #available(iOS 16.0, *) {
isShowingAssetPickerPopover = true
} else if horizontalSizeClass == .regular {
isShowingAssetPickerPopover = true isShowingAssetPickerPopover = true
} else { } else {
uiState.delegate?.presentAssetPickerSheet() uiState.delegate?.presentAssetPickerSheet()
@ -184,6 +191,7 @@ struct ComposeAttachmentsList: View {
} }
fileprivate extension View { fileprivate extension View {
@available(iOS, obsoleted: 15.0)
@ViewBuilder @ViewBuilder
func onDragWithPreviewIfAvailable<V>(_ data: @escaping () -> NSItemProvider, preview: () -> V) -> some View where V : View { func onDragWithPreviewIfAvailable<V>(_ data: @escaping () -> NSItemProvider, preview: () -> V) -> some View where V : View {
if #available(iOS 15.0, *) { if #available(iOS 15.0, *) {
@ -192,6 +200,45 @@ fileprivate extension View {
self.onDrag(data) self.onDrag(data)
} }
} }
@available(iOS, obsoleted: 16.0)
@ViewBuilder
func sheetOrPopover(isPresented: Binding<Bool>, @ViewBuilder content: @escaping () -> some View) -> some View {
if #available(iOS 16.0, *) {
self.modifier(SheetOrPopover(isPresented: isPresented, view: content))
} else {
self.popover(isPresented: isPresented, content: content)
}
}
@available(iOS, obsoleted: 16.0)
@ViewBuilder
func withSheetDetentsIfAvailable() -> some View {
if #available(iOS 16.0, *) {
self
.presentationDetents([.medium, .large])
.presentationDragIndicator(.visible)
} else {
self
}
}
}
@available(iOS 16.0, *)
struct SheetOrPopover<V: View>: ViewModifier {
@Binding var isPresented: Bool
@ViewBuilder let view: () -> V
@Environment(\.horizontalSizeClass) var sizeClass
func body(content: Content) -> some View {
let _ = print("isPresented: \(isPresented)")
if sizeClass == .compact {
content.sheet(isPresented: $isPresented, content: view)
} else {
content.popover(isPresented: $isPresented, content: view)
}
}
} }
//struct ComposeAttachmentsList_Previews: PreviewProvider { //struct ComposeAttachmentsList_Previews: PreviewProvider {

View File

@ -12,6 +12,7 @@ protocol ComposeUIStateDelegate: AnyObject {
var assetPickerDelegate: AssetPickerViewControllerDelegate? { get } var assetPickerDelegate: AssetPickerViewControllerDelegate? { get }
func dismissCompose(mode: ComposeUIState.DismissMode) func dismissCompose(mode: ComposeUIState.DismissMode)
// @available(iOS, obsoleted: 16.0)
func presentAssetPickerSheet() func presentAssetPickerSheet()
func presentComposeDrawing() func presentComposeDrawing()