Reputation: 158
I am trying to get answer from this question answer link but failed :(
iOS UIImagePickerController showed blank page
Then I try below code but still show blank screen without image list :( I think don't fire the delegation function You can also check from GitHub
https://github.com/MdAshfaqurRahmanIOS/image-picker-3
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
var imagePicker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
}
@IBAction func buttonAction(_ sender: UIButton) {
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = true
present(imagePicker, animated: true)
}
}
extension ViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[UIImagePickerController.InfoKey(rawValue: "UIImagePickerControllerEditedImage")] as? UIImage {
imageView.image = image
}
picker.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
}
Add this info.plist
key =>>>> Privacy - Photo Library Usage value =>> please access photogallery
Console log
Upvotes: 0
Views: 2174
Reputation: 5628
Try to follow my programmatically example below, first add your button and delegates to your controller and import Photo framework:
import UIKit
import Photos
class YourViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
lazy var takePicButton: UIButton = {
let button = UIButton()
button.backgroundColor = .red
button.setTitle("Present img picker", for: .normal)
button.setTitleColor(.white, for: .normal)
button.titleLabel?.font = .systemFont(ofSize: 16, weight: .semibold)
button.layer.cornerRadius = 14
button.clipsToBounds = true
button.addTarget(self, action: #selector(handlepickPicture), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
now in viewDidLoad add button and set constraints:
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(takePicButton)
takePicButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20).isActive = true
takePicButton.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20).isActive = true
takePicButton.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20).isActive = true
takePicButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
}
After that set your func to present image picker controller:
var imagePicker = UIImagePickerController()
@objc fileprivate func handlepickPicture() {
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.view.tintColor = .white
imagePicker.mediaTypes = ["public.image"]
imagePicker.allowsEditing = true
imagePicker.navigationBar.barTintColor = .black
checkPermission()
}
check the permission, don't forget to set your info.plist privacy usage description (like you):
fileprivate func checkPermission() {
let photoAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
switch photoAuthorizationStatus {
case .authorized:
print("Add Photo")
if UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum){
print("Access is granted by user")
self.present(imagePicker, animated: true, completion: nil)
}
print("Access is granted by user")
case .notDetermined:
PHPhotoLibrary.requestAuthorization({
(newStatus) in
print("status is \(newStatus)")
if newStatus == PHAuthorizationStatus.authorized {
/* do stuff here */
DispatchQueue.main.async {
self.present(self.imagePicker, animated: true, completion: nil)
}
print("success")
}
})
print("It is not determined until now")
case .restricted:
// same same
print("User do not have access to photo album.")
goToSetting()
case .denied:
// same same
print("Text tapped...")
goToSetting()
print("User has denied the permission.")
case .limited:
goToSetting() // the function show an alert to enable Authorization manually
print("User has denied the permission.")
@unknown default:
fatalError()
}
}
write the function to set authorization manually:
fileprivate func goToSetting() {
let title = "Oooooops!"
let message = "Hi man, for use this App press Go To settings and enabled access to Pohto Gallery... Check read and write option and relaunch the App!"
let alertController = UIAlertController(title: "", message: "", preferredStyle: .alert)
let subview = (alertController.view.subviews.first?.subviews.first?.subviews.first!)! as UIView
subview.backgroundColor = UIColor(white: 0, alpha: 0.2)
alertController.setValue(NSAttributedString(string: title, attributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 18, weight: .heavy),NSAttributedString.Key.foregroundColor : UIColor.red]), forKey: "attributedTitle")
alertController.setValue(NSAttributedString(string: message, attributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14, weight: .regular),NSAttributedString.Key.foregroundColor : UIColor.white]), forKey: "attributedMessage")
let cancelAction = UIAlertAction(title: "Cancel", style: .destructive) { (_) in
print("Action cancelled")
}
let goToSettingPermission = UIAlertAction(title: "Go To setting", style: .default) { (action) in
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
}
alertController.addAction(goToSettingPermission)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion: {
})
}
this is the result, on dx the alert for manual authorization, on left the picker controller
If you don't see the preview photos, try to run app with another simulator device.
Upvotes: 2
Reputation: 1014
You can use it by taking these photos into a collectionView like this "I've made it using RxSwift:
import UIKit
import RxSwift
import Foundation
import Photos
private let reuseIdentifier = "ImageCell"
class ImagesCollectionViewController: UICollectionViewController {
//MARK: - vars
private var images = [PHAsset]()
private var selectedPhotoSubject = PublishSubject<UIImage>()
var selectedPhoto: Observable<UIImage> {
return selectedPhotoSubject.asObservable()
}
//MARK: - LifeCycle
override func viewDidLoad() {
super.viewDidLoad()
linkPhotosLibrary()
self.title = "Pick an Image"
}
//MARK: - PhotoLibrary
private func linkPhotosLibrary() {
PHPhotoLibrary.requestAuthorization { [weak self] status in
if status == .authorized {
let assets = PHAsset.fetchAssets(with: PHAssetMediaType.image,options: nil)
assets.enumerateObjects { (object, count, stop) in
self?.images.append(object)
}
self?.images.reverse()
DispatchQueue.main.async {
self?.collectionView.reloadData()
}
}
}
}
// MARK: - UICollectionViewDataSource
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ImageCell
let asset = images[indexPath.row]
let manager = PHImageManager.default()
manager.requestImage(for: asset, targetSize: CGSize(width: 200,height: 200), contentMode: .aspectFit, options: nil) { image, _ in
DispatchQueue.main.async {
cell.imageViewOutlet.image = image
}
}
return cell
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedAsset = images[indexPath.row]
PHImageManager.default().requestImage(for: selectedAsset, targetSize: CGSize(width: 500, height: 500), contentMode: .aspectFit, options: nil) { [weak self] image , info in
guard let info = info else {return}
let isDegradedImage = info["PHImageResultIsDegradedKey"] as! Bool
// as we will call this function 2 times one for the small image in the collection and one here that's why we use it as this will tell us if the image is thumbnail or original image
if !isDegradedImage {
if let image = image {
self?.selectedPhotoSubject.onNext(image)
self?.dismiss(animated: true, completion: nil)
}
}
}
}
}
or you can use it normally:
var myGallery: GalleryController!
func showGalleryImages () {
self.myGallery = GalleryController()
self.myGallery.delegate = self
Config.tabsToShow = [.imageTab, .cameraTab]
Config.Camera.imageLimit = 100
self.present(self.myGallery, animated: true, completion: nil)
}
}
Upvotes: 1