diff --git a/Sources/SwiftUIBackports/Backport.swift b/Sources/SwiftUIBackports/Backport.swift index 5b0c5a4..704defb 100644 --- a/Sources/SwiftUIBackports/Backport.swift +++ b/Sources/SwiftUIBackports/Backport.swift @@ -29,7 +29,6 @@ import ObjectiveC /// } /// public struct Backport { - /// The underlying content this backport represents. public let content: Wrapped @@ -38,7 +37,12 @@ public struct Backport { public init(_ content: Wrapped) { self.content = content } +} +public extension Backport where Wrapped == Any { + init(_ content: Wrapped) { + self.content = content + } } public extension View { diff --git a/Sources/SwiftUIBackports/Shared/PasteButton/PasteButton.swift b/Sources/SwiftUIBackports/Shared/PasteButton/PasteButton.swift index 5cc64bc..9154307 100644 --- a/Sources/SwiftUIBackports/Shared/PasteButton/PasteButton.swift +++ b/Sources/SwiftUIBackports/Shared/PasteButton/PasteButton.swift @@ -165,7 +165,6 @@ struct PasteButtonStyle: PrimitiveButtonStyle { } } } -// .opacity(configuration.isPressed ? 0.5 : 1) } } #endif diff --git a/Sources/SwiftUIBackports/Shared/PhotosPicker/UIKit Hosts/PickerViewController.swift b/Sources/SwiftUIBackports/Shared/PhotosPicker/Hosts.swift similarity index 50% rename from Sources/SwiftUIBackports/Shared/PhotosPicker/UIKit Hosts/PickerViewController.swift rename to Sources/SwiftUIBackports/Shared/PhotosPicker/Hosts.swift index 3c36e7a..bb242b8 100644 --- a/Sources/SwiftUIBackports/Shared/PhotosPicker/UIKit Hosts/PickerViewController.swift +++ b/Sources/SwiftUIBackports/Shared/PhotosPicker/Hosts.swift @@ -14,6 +14,9 @@ internal extension View { library: PHPhotoLibrary ) -> some View { if #available(iOS 14, *) { + sheet(isPresented: isPresented) { + + } // var config = PHPickerConfiguration(photoLibrary: library) // config.preferredAssetRepresentationMode = preferredItemEncoding.mode // config.selectionLimit = maxSelectionCount ?? 0 @@ -29,13 +32,15 @@ internal extension View { // configuration: config // ) } else { - EmptyView() + backport.background { + LegacyPhotosViewController(isPresented: isPresented, selection: selection, filter: filter) + } } } } @available(iOS 14, *) -private struct PickerViewController: UIViewControllerRepresentable { +private struct PhotosViewController: UIViewControllerRepresentable { @Binding var isPresented: Bool @Binding var selection: [Backport.PhotosPickerItem] @@ -57,7 +62,7 @@ private struct PickerViewController: UIViewControllerRepresentable { } @available(iOS 14, *) -private extension PickerViewController { +private extension PhotosViewController { final class Representable: UIViewController, PHPickerViewControllerDelegate, UIAdaptivePresentationControllerDelegate { private weak var controller: PHPickerViewController? @@ -105,17 +110,121 @@ private extension PickerViewController { } private func dismissController() { + isPresented.wrappedValue = false guard let controller else { return } controller.presentedViewController?.dismiss(animated: true) } + func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { + print(results) + dismissController() + } + func presentationControllerDidDismiss(_ presentationController: UIPresentationController) { dismissController() } + } +} - func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { - print(results) - #warning("TBD") +@available(iOS 13, *) +private struct LegacyPhotosViewController: UIViewControllerRepresentable { + @Binding var isPresented: Bool + @Binding var selection: [Backport.PhotosPickerItem] + + let filter: Backport.PHPickerFilter? + + func makeUIViewController(context: Context) -> Representable { + Representable( + isPresented: $isPresented, + selection: $selection, + filter: filter + ) + } + + + func updateUIViewController(_ controller: Representable, context: Context) { + controller.selection = $selection + controller.filter = filter + } +} + +@available(iOS 13, *) +private extension LegacyPhotosViewController { + final class Representable: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UIAdaptivePresentationControllerDelegate { + private weak var controller: UIImagePickerController? + + var isPresented: Binding { + didSet { + updateControllerLifecycle( + from: oldValue.wrappedValue, + to: isPresented.wrappedValue + ) + } + } + + var selection: Binding<[Backport.PhotosPickerItem]> + var filter: Backport.PHPickerFilter? + + init(isPresented: Binding, selection: Binding<[Backport.PhotosPickerItem]>, filter: Backport.PHPickerFilter?) { + self.isPresented = isPresented + self.selection = selection + self.filter = filter + + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func updateControllerLifecycle(from oldValue: Bool, to newValue: Bool) { + switch (oldValue, newValue) { + case (false, true): + presentController() + case (true, false): + dismissController() + case (true, true), (false, false): + break + } + } + + private func presentController() { + let controller = UIImagePickerController() + + if let filter { + controller.mediaTypes = filter.mediaTypes + } else if let types = UIImagePickerController.availableMediaTypes(for: .photoLibrary) { + controller.mediaTypes = types + } + + controller.allowsEditing = false + controller.sourceType = .photoLibrary + controller.videoQuality = .typeHigh + controller.presentationController?.delegate = self + controller.delegate = self + + present(controller, animated: true) + self.controller = controller + } + + private func dismissController() { + isPresented.wrappedValue = false + guard let controller else { return } + controller.presentedViewController?.dismiss(animated: true) + } + + func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) { + print("TBD") + print(info) + dismissController() + } + + func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { + dismissController() + } + + func presentationControllerDidDismiss(_ presentationController: UIPresentationController) { + dismissController() } } } diff --git a/Sources/SwiftUIBackports/Shared/PhotosPicker/PhotosPicker.swift b/Sources/SwiftUIBackports/Shared/PhotosPicker/PhotosPicker.swift index 5ee5b84..df22564 100644 --- a/Sources/SwiftUIBackports/Shared/PhotosPicker/PhotosPicker.swift +++ b/Sources/SwiftUIBackports/Shared/PhotosPicker/PhotosPicker.swift @@ -2,22 +2,22 @@ import SwiftUI import PhotosUI -@available(iOS, introduced: 14, deprecated: 16) -public extension Backport where Wrapped == Any { - // Available when SwiftUI is imported with PhotosUI +@available(iOS, introduced: 13, deprecated: 16) +public extension Backport { + /// Available when SwiftUI is imported with PhotosUI /// A control that allows a user to choose photos and/or videos from the photo library. /// /// The user explicitly grants access only to items they choose, so photo library access authorization is not needed. struct PhotosPicker