Friday, November 6, 2026
HomeiOS DevelopmentChoosing photographs with UIImagePickerController in Swift 5

Choosing photographs with UIImagePickerController in Swift 5

[ad_1]

A reusable picture picker class for iOS

So on this tutorial we will create a reusable class constructed on high of UIKit so as to make picture choice extra nice on your apps, everyhing written in Swift 5.

This text was impressed by my earlier try to resolve the picture selecting problem in a protocol oriented method, however that article is these days just a little bit obsolated, plus I woundn’t use that approach anymore.

Individuals at all times study from the previous, so as a substitute of utilizing a protocol oriented strategy, this time I am going to merely go together with an ImagePicker class. No singletons, no further library, only a small helper class that may be instantiated within the acceptable place, to do it is job. 🌄

I am solely going to give attention to selecting edited photographs, if you would like to make use of dwell images or films, you may at all times customise the ImagePicker class, or create an summary one and implement subclasses for every media kind. I would achieve this too. 😅

So let’s dive in, right here is my primary implementation, however you may obtain an entire instance mission with video selecting as nicely from The.Swift.Dev. tutorials repository.

Privateness first!

These days privateness issues lots, so it’s important to add two necessary keys to your purposes Data.plist file, in any other case you may find yourself with a horrible crash! ⚠️



Because you’d prefer to get some non-public knowledge, it’s important to present an evidence message for the person (and for Apple) why the app is requesting digicam & picture library entry. The NSCameraUsageDescription is for digicam and NSPhotoLibraryUsageDescription secret’s for picture library entry. Each values must be an easy string that’ll clarify the person why you want his/her nude photos. Pricacy is necessary! 🔒


<key>NSCameraUsageDescription</key>
<string>This app desires to take photos.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app desires to make use of your images.</string>


Clearly if you would like to make use of images immediately taken from the digicam, however you do not wish to entry the picture library, you simply have so as to add the right key. That is it now we’re able to do some precise coding. ⌨️



The anatomy of UIImagePickerController

The anatomy of a UIPickerController is kind of easy. Mainly it is a common view controller, you simply should set just a few further properties to make it work.


let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.allowsEditing = true
pickerController.mediaTypes = ["public.image", "public.movie"]
pickerController.sourceType = .digicam


Permits enhancing is a flag that signifies if the resizing & cropping interface must be introduced after choosing & taking an image, if true you need to use the .editedImage as a substitute of the .originalImage key – contained in the picker delegate – to get the right picture from the picture information dictionary.

There are mainly two sorts of media varieties accessible: photographs and flicks. You may get the accessible media kind strings for every supply kind by calling a category methodology on the picker: UIImagePickerController.availableMediaTypes(for: .digicam).

There are 3 accessible supply varieties: .digicam, which is the digicam, and there are two different choices to get photos from the picture library. The .photoLibrary enum case gives you full entry, however you may restrict the choice scope just for the digicam roll when you select .savedPhotosAlbum.

The delegate ought to implement each the UIImagePickerControllerDelegate and the UINavigationControllerDelegate protocols, nonetheless normally my navigation controller delegate is simply an empty implementation. Should you want further navigation associated logic, you would possibly have to create just a few strategies there as nicely.

Awww, let’s simply put every part collectively…


import UIKit

public protocol ImagePickerDelegate: class {
    func didSelect(picture: UIImage?)
}

open class ImagePicker: NSObject {

    non-public let pickerController: UIImagePickerController
    non-public weak var presentationController: UIViewController?
    non-public weak var delegate: ImagePickerDelegate?

    public init(presentationController: UIViewController, delegate: ImagePickerDelegate) {
        self.pickerController = UIImagePickerController()

        tremendous.init()

        self.presentationController = presentationController
        self.delegate = delegate

        self.pickerController.delegate = self
        self.pickerController.allowsEditing = true
        self.pickerController.mediaTypes = ["public.image"]
    }

    non-public func motion(for kind: UIImagePickerController.SourceType, title: String) -> UIAlertAction? {
        guard UIImagePickerController.isSourceTypeAvailable(kind) else {
            return nil
        }

        return UIAlertAction(title: title, model: .default) { [unowned self] _ in
            self.pickerController.sourceType = kind
            self.presentationController?.current(self.pickerController, animated: true)
        }
    }

    public func current(from sourceView: UIView) {

        let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

        if let motion = self.motion(for: .digicam, title: "Take picture") {
            alertController.addAction(motion)
        }
        if let motion = self.motion(for: .savedPhotosAlbum, title: "Digicam roll") {
            alertController.addAction(motion)
        }
        if let motion = self.motion(for: .photoLibrary, title: "Picture library") {
            alertController.addAction(motion)
        }

        alertController.addAction(UIAlertAction(title: "Cancel", model: .cancel, handler: nil))

        if UIDevice.present.userInterfaceIdiom == .pad {
            alertController.popoverPresentationController?.sourceView = sourceView
            alertController.popoverPresentationController?.sourceRect = sourceView.bounds
            alertController.popoverPresentationController?.permittedArrowDirections = [.down, .up]
        }

        self.presentationController?.current(alertController, animated: true)
    }

    non-public func pickerController(_ controller: UIImagePickerController, didSelect picture: UIImage?) {
        controller.dismiss(animated: true, completion: nil)

        self.delegate?.didSelect(picture: picture)
    }
}

extension ImagePicker: UIImagePickerControllerDelegate {

    public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        self.pickerController(picker, didSelect: nil)
    }

    public func imagePickerController(_ picker: UIImagePickerController,
                                      didFinishPickingMediaWithInfo information: [UIImagePickerController.InfoKey: Any]) {
        guard let picture = information[.editedImage] as? UIImage else {
            return self.pickerController(picker, didSelect: nil)
        }
        self.pickerController(picker, didSelect: picture)
    }
}

extension ImagePicker: UINavigationControllerDelegate {

}


Should you need not choose from a supply kind, issues are fairly easy, you may merely current your picker view controller, deal with every part within the delegate and you’re completed. Nevertheless, if you should select from an enter supply, that includes just a little bit extra logic, particularly on iPads. 📱

I am utilizing a UIAlertController so as to compose a supply kind choice dialog. I am attempting so as to add 3 actions (based mostly on the selecting supply kind), however provided that the supply kind is out there on that given system (eg. .digicam just isn’t accessible within the simulator). You may test availability by: UIImagePickerController.isSourceTypeAvailable(kind).


Alert controllers wants just a few further issues on iPads, that is why I am organising the popoverPresentationController properties within the current methodology. It is normally sufficient to set the sourceView and the sourceRect properties, however you can too customise arrow instructions. ⬅️➡️⬆️⬇️

It is at all times your process to test if the system is an iPad & set the right supply view & rect if it is wanted, in any other case your app will crash on iPads. One other factor is that it’s important to dismiss the UIPickerViewController after the picker did it is job! ⚠️

Time to say cheese! 🧀

Easy methods to use the picture picker class?

Properly, now you’re able to take some photos. I’ve made a easy view controller to indicate you an actual fast instance. You solely want a UIImageView and a UIButton.



Now that is the code for the pattern view controller. Nothing magical, I simply go the controller as a presentationController for the ImagePicker so it’s going to have the ability to current the UIImagePickerController on high of that. I separated the delegate from the presentation controller, as a result of generally it comes helpful. 🤷‍♂️


class ViewController: UIViewController {

    @IBOutlet var imageView: UIImageView!

    var imagePicker: ImagePicker!

    override func viewDidLoad() {
        tremendous.viewDidLoad()

        self.imagePicker = ImagePicker(presentationController: self, delegate: self)
    }

    @IBAction func showImagePicker(_ sender: UIButton) {
        self.imagePicker.current(from: sender)
    }
}

extension ViewController: ImagePickerDelegate {

    func didSelect(picture: UIImage?) {
        self.imageView.picture = picture
    }
}


The ImagePickerDelegate delegate on this case is the most straightforward one I can think about. It simply offers the picked picture so that you’re prepared to make use of it. Nevertheless in some circumstances you would possibly want just a few additonal information from the picture picker.

If you wish to take this strategy one step additional, you may create an summary class or a protocol that defines the fundamental performance and based mostly on you could implement numerous media picker controllers to suit your wants. Anyway, my level right here was to replace an outdated article, comply with me & subscribe for extra UIKit ideas & methods!





[ad_2]

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments