The PHPickerViewController
class is the new system picker that allows you to get access to images and videos from the user’s photo library.
PHPickerViewController
is an alternative to UIImagePickerController with ability to select more than one image at once. UIImagePickerController
was a good choice before iOS 14.0 as simple image picker.
Contrarily to the UIImagePickerController
, PHPicker provides a better privacy and does not require to ask for user consent so it can be used.
UIKit
import UIKit import PhotosUI class PhotosUIViewController: UIViewController { lazy var addButton: UIButton = { let v = UIButton(type: .system) v.setTitle("Add", for: .normal) v.translatesAutoresizingMaskIntoConstraints = false v.addTarget(self, action: #selector(handleAdd), for: .touchUpInside) return v }() lazy var stackView: UIStackView = { let v = UIStackView(arrangedSubviews: [addButton]) v.translatesAutoresizingMaskIntoConstraints = false v.axis = .vertical v.distribution = .fillProportionally v.spacing = 8 v.alignment = .fill return v }() override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white view.addSubview(stackView) NSLayoutConstraint.activate([ stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor), stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor), stackView.topAnchor.constraint(equalTo: view.topAnchor), stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) } } extension PhotosUIViewController: PHPickerViewControllerDelegate { @objc func handleAdd() { var config = PHPickerConfiguration() config.selectionLimit = 0 config.filter = PHPickerFilter.images let pickerViewController = PHPickerViewController(configuration: config) pickerViewController.delegate = self self.present(pickerViewController, animated: true, completion: nil) } func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { picker.dismiss(animated: true, completion: nil) for result in results { result.itemProvider.loadObject(ofClass: UIImage.self, completionHandler: { [weak self] (object, error) in if let image = object as? UIImage { DispatchQueue.main.async { [weak self] in self?.stackView.addArrangedSubview(UIImageView(image: image)) } } }) } } }
SwiftUI
You can use following snippet starting from iOS 16.0. To use PHPicker on 14.0 iOS version or above you have to wrap it in UIViewControllerRepresentable
.
import SwiftUI import PhotosUI struct PhotoView: View { @State var photoItems = [PhotosPickerItem]() @State var selectedPhotos = [UIImage]() var body: some View { VStack { if !selectedPhotos.isEmpty { ScrollView(showsIndicators: false) { ForEach(selectedPhotos, id: \.self) { photo in Image(uiImage: photo) .resizable() .scaledToFit() .frame(width: 200, height: 200) } } } PhotosPicker(selection: $photoItems, maxSelectionCount: 0, matching: .images) { Label("Select photos", systemImage: "photo") } .onChange(of: photoItems) { newItems in newItems.forEach { item in Task { guard let data = try? await item.loadTransferable(type: Data.self) else { return } guard let image = UIImage(data: data) else { return } selectedPhotos.append(image) } } } } } }