diff --git a/Package.swift b/Package.swift index 744874c2..027f42be 100644 --- a/Package.swift +++ b/Package.swift @@ -1,11 +1,11 @@ -// swift-tools-version:5.8 +// swift-tools-version:5.7 import PackageDescription let package = Package( name: "ImagePicker", platforms: [ - .iOS(.v10) + .iOS(.v15) ], products: [ // Products define the executables and libraries produced by a package, and make them visible to other packages. diff --git a/Source/BottomView/BottomContainerView.swift b/Source/BottomView/BottomContainerView.swift index 1133cf9b..acfb70e1 100644 --- a/Source/BottomView/BottomContainerView.swift +++ b/Source/BottomView/BottomContainerView.swift @@ -1,6 +1,6 @@ import UIKit -protocol BottomContainerViewDelegate: class { +protocol BottomContainerViewDelegate: AnyObject { func pickerButtonDidPress() func doneButtonDidPress() diff --git a/Source/BottomView/ButtonPicker.swift b/Source/BottomView/ButtonPicker.swift index 87c01aae..ce9dc766 100644 --- a/Source/BottomView/ButtonPicker.swift +++ b/Source/BottomView/ButtonPicker.swift @@ -1,6 +1,6 @@ import UIKit -protocol ButtonPickerDelegate: class { +protocol ButtonPickerDelegate: AnyObject { func buttonDidPress() } diff --git a/Source/BottomView/StackView.swift b/Source/BottomView/StackView.swift index 9402c8ba..5ee73d1c 100644 --- a/Source/BottomView/StackView.swift +++ b/Source/BottomView/StackView.swift @@ -1,7 +1,7 @@ import UIKit import Photos -protocol ImageStackViewDelegate: class { +protocol ImageStackViewDelegate: AnyObject { func imageStackViewDidPress() } diff --git a/Source/CameraView/CameraMan.swift b/Source/CameraView/CameraMan.swift index 8714823f..846d0875 100644 --- a/Source/CameraView/CameraMan.swift +++ b/Source/CameraView/CameraMan.swift @@ -2,7 +2,7 @@ import Foundation import AVFoundation import PhotosUI -protocol CameraManDelegate: class { +protocol CameraManDelegate: AnyObject { func cameraManNotAvailable(_ cameraMan: CameraMan) func cameraManDidStart(_ cameraMan: CameraMan) func cameraMan(_ cameraMan: CameraMan, didChangeInput input: AVCaptureDeviceInput) @@ -30,27 +30,29 @@ class CameraMan { checkPermission() } - func setupDevices() { - // Input - AVCaptureDevice - .devices() - .filter { - return $0.hasMediaType(AVMediaType.video) - }.forEach { - switch $0.position { - case .front: - self.frontCamera = try? AVCaptureDeviceInput(device: $0) - case .back: - self.backCamera = try? AVCaptureDeviceInput(device: $0) - default: - break - } + func setupDevices() { + // Input + let discoverySession = AVCaptureDevice.DiscoverySession( + deviceTypes: [.builtInWideAngleCamera], + mediaType: .video, + position: .unspecified + ) + + let devices = discoverySession.devices + + for device in devices { + switch device.position { + case .front: + self.frontCamera = try? AVCaptureDeviceInput(device: device) + case .back: + self.backCamera = try? AVCaptureDeviceInput(device: device) + default: + break + } + } } - // Output - stillImageOutput = AVCaptureStillImageOutput() - stillImageOutput?.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG] - } + func addInput(_ input: AVCaptureDeviceInput) { configurePreset(input) diff --git a/Source/CameraView/CameraView.swift b/Source/CameraView/CameraView.swift index c190224f..616f1cfc 100644 --- a/Source/CameraView/CameraView.swift +++ b/Source/CameraView/CameraView.swift @@ -2,7 +2,7 @@ import UIKit import AVFoundation import PhotosUI -protocol CameraViewDelegate: class { +protocol CameraViewDelegate: AnyObject { func setFlashButtonHidden(_ hidden: Bool) func imageToLibrary() @@ -55,25 +55,25 @@ class CameraView: UIViewController, CLLocationManagerDelegate, CameraManDelegate return label }() - lazy var noCameraButton: UIButton = { [unowned self] in - let button = UIButton(type: .system) - let title = NSAttributedString(string: self.configuration.settingsTitle, - attributes: [ - NSAttributedString.Key.font: self.configuration.settingsFont, - NSAttributedString.Key.foregroundColor: self.configuration.settingsColor - ]) - - button.setAttributedTitle(title, for: UIControl.State()) - button.contentEdgeInsets = UIEdgeInsets(top: 5.0, left: 10.0, bottom: 5.0, right: 10.0) - button.sizeToFit() - button.layer.borderColor = self.configuration.settingsColor.cgColor - button.layer.borderWidth = 1 - button.layer.cornerRadius = 4 - button.addTarget(self, action: #selector(settingsButtonDidTap), for: .touchUpInside) - - return button + lazy var noCameraButton: UIButton = { [unowned self] in + var buttonConfig = UIButton.Configuration.tinted() + buttonConfig.title = self.configuration.settingsTitle + buttonConfig.baseForegroundColor = self.configuration.settingsColor + buttonConfig.titlePadding = 10.0 + buttonConfig.image = nil + buttonConfig.cornerStyle = .small + buttonConfig.imagePadding = 5.0 + + let button = UIButton(configuration: buttonConfig) + button.sizeToFit() + button.layer.borderWidth = 1 + button.layer.borderColor = self.configuration.settingsColor.cgColor + button.addTarget(self, action: #selector(settingsButtonDidTap), for: .touchUpInside) + + return button }() + lazy var tapGestureRecognizer: UITapGestureRecognizer = { [unowned self] in let gesture = UITapGestureRecognizer() gesture.addTarget(self, action: #selector(tapGestureRecognizerHandler(_:))) @@ -185,13 +185,14 @@ class CameraView: UIViewController, CLLocationManagerDelegate, CameraManDelegate // MARK: - Actions - @objc func settingsButtonDidTap() { - DispatchQueue.main.async { - if let settingsURL = URL(string: UIApplication.openSettingsURLString) { - UIApplication.shared.openURL(settingsURL) - } + @objc func settingsButtonDidTap() { + DispatchQueue.main.async { + if let settingsURL = URL(string: UIApplication.openSettingsURLString) { + UIApplication.shared.open(settingsURL, options: [:], completionHandler: nil) + } + } } - } + // MARK: - Camera actions diff --git a/Source/Extensions/ConstraintsSetup.swift b/Source/Extensions/ConstraintsSetup.swift index 66829a70..011d4d1f 100644 --- a/Source/Extensions/ConstraintsSetup.swift +++ b/Source/Extensions/ConstraintsSetup.swift @@ -118,20 +118,19 @@ extension ImagePickerController { relatedBy: .equal, toItem: view, attribute: attribute, multiplier: 1, constant: 0)) } - let bottomHeightPadding: CGFloat - if #available(iOS 11.0, *) { + var bottomHeightPadding: CGFloat = 0 + view.addConstraint(NSLayoutConstraint(item: galleryView, attribute: .top, relatedBy: .equal, toItem: view.safeAreaLayoutGuide, attribute: .top, multiplier: 1, constant: 0)) - bottomHeightPadding = UIApplication.shared.keyWindow!.safeAreaInsets.bottom - } else { - view.addConstraint(NSLayoutConstraint(item: galleryView, attribute: .top, - relatedBy: .equal, toItem: view, - attribute: .top, - multiplier: 1, constant: 0)) - bottomHeightPadding = 0 - } + if let windowScene = UIApplication.shared.connectedScenes + .compactMap({ $0 as? UIWindowScene }) + .first(where: { $0.activationState == .foregroundActive }), + let window = windowScene.windows.first(where: { $0.isKeyWindow }) { + bottomHeightPadding = window.safeAreaInsets.bottom + } + view.addConstraint(NSLayoutConstraint(item: galleryView, attribute: .height, relatedBy: .equal, toItem: view, attribute: .height, multiplier: 1, constant: -(BottomContainerView.Dimensions.height + bottomHeightPadding))) @@ -150,17 +149,10 @@ extension ImagePickerController { multiplier: 1, constant: 0)) } - if #available(iOS 11.0, *) { view.addConstraint(NSLayoutConstraint(item: topView, attribute: .top, relatedBy: .equal, toItem: view.safeAreaLayoutGuide, attribute: .top, multiplier: 1, constant: 0)) - } else { - view.addConstraint(NSLayoutConstraint(item: topView, attribute: .top, - relatedBy: .equal, toItem: view, - attribute: .top, - multiplier: 1, constant: 0)) - } view.addConstraint(NSLayoutConstraint(item: topView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, @@ -170,21 +162,20 @@ extension ImagePickerController { relatedBy: .equal, toItem: view, attribute: .height, multiplier: 1, constant: -BottomContainerView.Dimensions.height)) } - - if #available(iOS 11.0, *) { - let heightPadding = UIApplication.shared.keyWindow!.safeAreaInsets.bottom + var heightPadding:CGFloat = 0 + if let windowScene = UIApplication.shared.connectedScenes + .compactMap({ $0 as? UIWindowScene }) + .first(where: { $0.activationState == .foregroundActive }), + let window = windowScene.windows.first(where: { $0.isKeyWindow }) { + heightPadding = window.safeAreaInsets.bottom + } + view.addConstraint(NSLayoutConstraint(item: bottomContainer, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: BottomContainerView.Dimensions.height + heightPadding)) - } else { - view.addConstraint(NSLayoutConstraint(item: bottomContainer, attribute: .height, - relatedBy: .equal, toItem: nil, - attribute: .notAnAttribute, - multiplier: 1, - constant: BottomContainerView.Dimensions.height)) - } + } } diff --git a/Source/ImageGallery/ImageGalleryView.swift b/Source/ImageGallery/ImageGalleryView.swift index 27eb31ca..c314f121 100644 --- a/Source/ImageGallery/ImageGalleryView.swift +++ b/Source/ImageGallery/ImageGalleryView.swift @@ -12,7 +12,7 @@ private func < (lhs: T?, rhs: T?) -> Bool { } } -protocol ImageGalleryPanGestureDelegate: class { +protocol ImageGalleryPanGestureDelegate: AnyObject { func panGestureDidStart() func panGestureDidChange(_ translation: CGPoint) diff --git a/Source/ImagePickerController.swift b/Source/ImagePickerController.swift index 5ccf6754..5b622201 100644 --- a/Source/ImagePickerController.swift +++ b/Source/ImagePickerController.swift @@ -136,17 +136,22 @@ open class ImagePickerController: UIViewController { setupConstraints() } - open override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) + open override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) - if configuration.managesAudioSession { - _ = try? AVAudioSession.sharedInstance().setActive(true) - } + if configuration.managesAudioSession { + _ = try? AVAudioSession.sharedInstance().setActive(true) + } + + if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene { + let statusBarManager = windowScene.statusBarManager + //statusBarManager?.statusBarStyle = .default + //statusBarManager.statusBar?.isHidden = false // Adjust the visibility as needed + } - statusBarHidden = UIApplication.shared.isStatusBarHidden + self.handleRotation(nil) + } - self.handleRotation(nil) - } open override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) @@ -195,24 +200,25 @@ open class ImagePickerController: UIViewController { } } - func presentAskPermissionAlert() { - let alertController = UIAlertController(title: configuration.requestPermissionTitle, message: configuration.requestPermissionMessage, preferredStyle: .alert) + func presentAskPermissionAlert() { + let alertController = UIAlertController(title: configuration.requestPermissionTitle, message: configuration.requestPermissionMessage, preferredStyle: .alert) - let alertAction = UIAlertAction(title: configuration.OKButtonTitle, style: .default) { _ in - if let settingsURL = URL(string: UIApplication.openSettingsURLString) { - UIApplication.shared.openURL(settingsURL) - } - } + let alertAction = UIAlertAction(title: configuration.OKButtonTitle, style: .default) { _ in + if let settingsURL = URL(string: UIApplication.openSettingsURLString) { + UIApplication.shared.open(settingsURL, options: [:], completionHandler: nil) + } + } - let cancelAction = UIAlertAction(title: configuration.cancelButtonTitle, style: .cancel) { _ in - self.dismiss(animated: true, completion: nil) - } + let cancelAction = UIAlertAction(title: configuration.cancelButtonTitle, style: .cancel) { _ in + self.dismiss(animated: true, completion: nil) + } - alertController.addAction(alertAction) - alertController.addAction(cancelAction) + alertController.addAction(alertAction) + alertController.addAction(cancelAction) + + present(alertController, animated: true, completion: nil) + } - present(alertController, animated: true, completion: nil) - } func hideViews() { enableGestures(false) diff --git a/Source/TopView/TopView.swift b/Source/TopView/TopView.swift index 7c6f067e..06894f16 100644 --- a/Source/TopView/TopView.swift +++ b/Source/TopView/TopView.swift @@ -1,6 +1,6 @@ import UIKit -protocol TopViewDelegate: class { +protocol TopViewDelegate: AnyObject { func flashButtonDidPress(_ title: String) func rotateDeviceDidPress() @@ -19,22 +19,30 @@ open class TopView: UIView { var currentFlashIndex = 0 let flashButtonTitles = ["AUTO", "ON", "OFF"] - open lazy var flashButton: UIButton = { [unowned self] in - let button = UIButton() - button.setImage(AssetManager.getImage("AUTO"), for: UIControl.State()) - button.setTitle("AUTO", for: UIControl.State()) - button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 4, bottom: 0, right: 0) - button.setTitleColor(UIColor.white, for: UIControl.State()) - button.setTitleColor(UIColor.white, for: .highlighted) - button.titleLabel?.font = self.configuration.flashButton - button.addTarget(self, action: #selector(flashButtonDidPress(_:)), for: .touchUpInside) - button.contentHorizontalAlignment = .left - button.accessibilityLabel = "Flash mode is auto" - button.accessibilityHint = "Double-tap to change flash mode" - - return button + open lazy var flashButton: UIButton = { [unowned self] in + var config = UIButton.Configuration.plain() + config.image = AssetManager.getImage("AUTO") + config.title = "AUTO" + config.imagePadding = 4 + config.baseForegroundColor = UIColor.white + config.baseBackgroundColor = UIColor.clear + //config.titleHighlightedColor = UIColor.white // Set the highlighted text color here + //config.titleFont = self.configuration.flashButton + + let button = UIButton(configuration: config) + button.addAction(UIAction(handler: { [weak self] _ in + self?.flashButtonDidPress(button) + }), for: .touchUpInside) + + button.contentHorizontalAlignment = .left + button.accessibilityLabel = "Flash mode is auto" + button.accessibilityHint = "Double-tap to change flash mode" + + return button }() + + open lazy var rotateCamera: UIButton = { [unowned self] in let button = UIButton() button.accessibilityLabel = ""