Skip to content

UIImagePickerController

UIImagePickerController is a UIKit class that provides a standard interface for selecting or capturing photos and videos from the device’s camera or photo library. It simplifies media selection by presenting a system-provided UI for accessing the camera, photo library, or saved photos album. This document covers the usage of UIImagePickerController in UIKit-based iOS applications.

Purpose

  • Media Selection: Allows users to pick images or videos from the photo library or take new ones with the camera.
  • Standard UI: Provides a consistent, native interface for media access.
  • Customizable: Supports configuration for source type, media types, and editing options.

Key Features

  • Source Types: Supports .camera, .photoLibrary, and .savedPhotosAlbum.
  • Media Types: Allows selection of images (public.image), movies (public.movie), or both.
  • Editing: Enables in-place cropping or editing of selected media.
  • Delegate: Uses a delegate to handle selection and dismissal events.

Basic Usage

UIImagePickerController is presented modally, configured with a source type and media types, and requires a delegate conforming to UIImagePickerControllerDelegate and UINavigationControllerDelegate.

Example: Selecting an Image from Photo Library

swift
import UIKit

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    @IBOutlet weak var imageView: UIImageView!
    
    @IBAction func pickImage(_ sender: UIButton) {
        let picker = UIImagePickerController()
        picker.delegate = self
        picker.sourceType = .photoLibrary
        picker.allowsEditing = true // Enable cropping/editing
        picker.mediaTypes = ["public.image"] // Only images
        
        present(picker, animated: true, completion: nil)
    }
    
    // Delegate method for image selection
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let editedImage = info[.editedImage] as? UIImage {
            imageView.image = editedImage
        } else if let originalImage = info[.originalImage] as? UIImage {
            imageView.image = originalImage
        }
        
        dismiss(animated: true, completion: nil)
    }
    
    // Delegate method for cancellation
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        dismiss(animated: true, completion: nil)
    }
}

Key Points

  • Source Type: Set sourceType to .camera, .photoLibrary, or .savedPhotosAlbum. Check availability with isSourceTypeAvailable(_:).
  • Media Types: Specify media types using UTI strings (e.g., public.image, public.movie).
  • Editing: Set allowsEditing = true to enable cropping or editing.
  • Delegate: Implement UIImagePickerControllerDelegate to handle selection (didFinishPickingMediaWithInfo) and cancellation (imagePickerControllerDidCancel).
  • Presentation: Present modally using present(_:animated:completion:).

Advanced Features

Checking Source Availability

Ensure the source is available before presenting:

swift
if UIImagePickerController.isSourceTypeAvailable(.camera) {
    picker.sourceType = .camera
} else {
    print("Camera not available")
}

Configuring Camera

Customize camera settings:

swift
picker.sourceType = .camera
picker.cameraCaptureMode = .photo // or .video
picker.cameraDevice = .rear // or .front
picker.showsCameraControls = true
picker.cameraFlashMode = .auto // or .on, .off

Handling Video

Allow video selection and set quality or duration:

swift
picker.mediaTypes = ["public.movie"]
picker.videoQuality = .typeHigh // or .typeMedium, .typeLow
picker.videoMaximumDuration = 30 // Seconds

Retrieve video URL:

swift
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    if let videoURL = info[.mediaURL] as? URL {
        print("Selected video: \(videoURL)")
    }
    dismiss(animated: true, completion: nil)
}

Customizing the Interface

Overlay custom views on the camera:

swift
picker.showsCameraControls = false
let overlayView = UIView(frame: picker.view.bounds)
overlayView.backgroundColor = .clear
// Add custom UI elements to overlayView
picker.cameraOverlayView = overlayView

iPad Popover

On iPad, present the picker in a popover:

swift
if UIDevice.current.userInterfaceIdiom == .pad {
    picker.modalPresentationStyle = .popover
    if let popover = picker.popoverPresentationController {
        popover.sourceView = sender
        popover.sourceRect = sender.bounds
        popover.permittedArrowDirections = .any
    }
}

Editing Configuration

Control the editing experience:

swift
picker.allowsEditing = true
// Access crop rectangle or edited media
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    if let cropRect = info[.cropRect] as? CGRect {
        print("Crop rectangle: \(cropRect)")
    }
    if let editedImage = info[.editedImage] as? UIImage {
        imageView.image = editedImage
    }
}

Permissions

Accessing the camera or photo library requires user permission. Add these keys to Info.plist:

  • Camera: NSCameraUsageDescription
  • Photo Library: NSPhotoLibraryUsageDescription

Example:

xml
<key>NSCameraUsageDescription</key>
<string>We need camera access to take photos.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need photo library access to select images.</string>

Request permission programmatically (using PHPhotoLibrary for photos):

swift
import Photos

PHPhotoLibrary.requestAuthorization { status in
    if status == .authorized {
        // Present picker
    } else {
        print("Photo library access denied")
    }
}

Best Practices

  • Permission Handling: Request permissions before presenting the picker and handle denial gracefully.
  • Source Availability: Always check isSourceTypeAvailable(_:) before setting sourceType.
  • Delegate Management: Ensure the delegate is set and conforms to both UIImagePickerControllerDelegate and UINavigationControllerDelegate.
  • Memory: Handle large images or videos carefully to avoid memory issues.
  • Accessibility: Ensure the picker’s UI is accessible with VoiceOver.
  • Testing: Test on various devices (iPhone, iPad) and scenarios (camera vs. library, iPad popover).
  • iPad Popover: Configure popoverPresentationController for iPad to avoid crashes.

Limitations

  • System UI: Limited customization of the picker’s interface (except camera overlay).
  • iOS Only: UIImagePickerController is UIKit-specific and unavailable in macOS without Mac Catalyst.
  • Permissions: Requires explicit user permission, which may be denied.
  • Editing: Editing features are basic; for advanced editing, use a custom solution or third-party library.

Summary

UIImagePickerController provides a native, user-friendly interface for selecting or capturing photos and videos in UIKit apps. With support for camera, photo library, editing, and customizable settings, it simplifies media handling. By following best practices, including permission management and iPad popover configuration, developers can create seamless media selection experiences.

Released under the MIT License.