All iOS 9 devices have at least one camera. When a user takes a picture with the camera, the image is stored in the device's photo library. This lesson shows you how to allow the user to pick an image from the photo library or take a new picture with the camera and use it in your application.
The UIKit framework contains a class called UIImagePickerController
designed specifically to allow you to access the camera and photo library from your applications. This class presents its own user interface (see Figure 31.1) that allows a user to browse through the photo library or control the camera. All you have to do is present this view controller in your application and provide a delegate method whose methods are called when the user has finished selecting an image.
The image picker controller can also be used to record videos and access these recorded videos within your application.
The UIImagePickerController
class can be used to access the contents of either the photo library, saved photos album, or the camera. You can specify the source by providing a value for the sourceType
property. This value can be one of the following:
UIImagePickerControllerSourceType.PhotoLibrary
UIImagePickerControllerSourceType.Camera
UIImagePickerControllerSourceType.SavedPhotosAlbum
To check if a particular source type is available, use the isSourceTypeAvailable(sourceType: UIImagePickerControllerSourceType) -> Bool
class method of the UIImagePickerController
class as follows:
let hasCamera:Bool = UIImagePickerController.isSourceTypeAvailable(
UIImagePickerControllerSourceType.Camera)
When the sourceType
is set to use the camera, you can specify which camera is to be used if your device has multiple cameras. By default, the image picker uses the rear camera. To find out if front and rear cameras are available, use the isCameraDeviceAvailable(cameraDevice: UIImagePickerControllerCameraDevice) -> Bool
class method, as shown in the following code snippet:
let hasFrontCamera:Bool =
UIImagePickerController.isCameraDeviceAvailable(
UIImagePickerControllerCameraDevice.Front);
let hasRearCamera:Bool =
UIImagePickerController.isCameraDeviceAvailable(
UIImagePickerControllerCameraDevice.Rear);
Once you have determined that the camera you want to use is available, you can specify it using the cameraDevice
property of the image picker instance. For instance, to use the front camera, use the following code:
imagePicker.cameraDevice = UIImagePickerControllerCameraDevice.Front;
To display the image picker as a modal sheet, use the presentViewController(viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)?)
method on your active view controller object:
self.presentViewController(imagePicker, animated: true, completion: nil)
On an iPad, you can also display an image picker in a popover controller. The following code snippet shows how this can be done programmatically from a method in your view controller class:
if UIDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad
{
imagePicker.modalPresentationStyle = UIModalPresentationStyle.Popover
self.presentViewController(imagePicker, animated: true, completion: nil)
// Get the popover presentation controller and configure it.
let presentationController:UIPopoverPresentationController =
imagePicker.popoverPresentationController!
presentationController.permittedArrowDirections =
UIPopoverArrowDirection.Left
presentationController.sourceView = self.view
presentationController.sourceRect = popoverPresetingButton.frame
}
The preceding code assumes that you have imagePicker
as an instance of UIImagePickerController
and popoverPresentingButton
as an outlet in your view controller class.
UIImagePickerController
requires a delegate object that implements both the UIImagePickerControllerDelegate
and UINavigationControllerDelegate
protocols. The former defines two methods that are called when the user has selected an image or selected the Cancel button in the image picker:
func imagePickerController(picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject])
func imagePickerControllerDidCancel(picker: UIImagePickerController)
The imagePickerControllerDidCancel(picker: UIImagePickerController)
delegate method has one parameter that contains a reference to the image picker controller. A typical implementation of this delegate method dismisses the image picker controller if it was presented modally:
picker.dismissViewControllerAnimated(true, completion: nil)
The imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
delegate method has two parameters, the first of which is a reference to the image picker. The second parameter is an NSDictionary
object that contains a UIImage
object corresponding to the selected image.
To access this image in this delegate method, you can use code similar to the following to retrieve the value in the dictionary that corresponds to the UIImagePickerControllerOriginalImage
key:
let image:UIImage = info[UIImagePickerControllerOriginalImage] as! UIImage
Often, you may want to save this UIImage
instance to a file. To do that, you must first obtain an NSData
instance that contains the pixels in the UIImage
instance in a specific file format. Once you have this NSData
instance, you can write it to a file by sending it the writeToFile:atomically:
message.
To obtain an NSData
instance that contains the image as a PNG file, use the UIImagePNGRepresentation
function as follows:
let imageData:NSData = UIImagePNGRepresentation(image)!
To obtain an NSData
instance that contains the image in JPEG format, use the UIImageJPEGRepresentation
function as follows:
let imageData:NSData = UIImageJPEGRepresentation(image, 1.0)!
The first parameter to this function is the UIImage
instance; the second is a number between 0.0 and 1.0 that indicates the desired JPEG quality, with 0.0 being representing the lowest quality and 1.0 the highest quality.
The following implementation of the imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
delegate method shows how to save the selected image to a PNG file in the Documents directory:
func imagePickerController(picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject])
{
let image:UIImage = info[UIImagePickerControllerOriginalImage] as!
UIImage
let imageData:NSData = UIImagePNGRepresentation(image)!
let documentsDirectory =
NSSearchPathForDirectoriesInDomains(.DocumentDirectory,
.UserDomainMask,
true)[0]
let outFile:String = documentsDirectory + "savedImage.png"
imageData.writeToFile(outFile, atomically: true)
picker.dismissViewControllerAnimated(true, completion: nil)
}
If you provide a delegate for the image picker, then you are responsible for dismissing the picker. To do so, add the following line of code:
picker.dismissViewControllerAnimated(true, completion: nil)
to the end of both delegate methods:
imagePickerControllerDidCancel(picker: UIImagePickerController)
imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
In this Try It, you build an iPhone application based on the Single View Application template called ImagePicker
that allows the user to select an image from the photo library, or take a picture using the camera and display the image in an image view.
UIImageView
instance to the scene and an appropriate outlet in the view controller file.UIButton
instances to the scene and connect them to appropriate action methods in the view controller class.ImagePicker
.
UIImageView
instance to the default scene and connect it to an outlet in the view controller class.
imageView
.UIButton
instances to the scene and connect their Touch Up Inside events to appropriate action methods in the view controller class.
UIButton
instances onto the default scene and position them one below the other (see Figure 31.2).
Camera
. Set its background color to a shade of gray.Photo Library
. Set its background color to a shade of gray.onCamera
.onPhotoLibrary
.cameraButton
in the view controller class and connect it to the button titled Camera in the scene.Table 31.1 Layout Constraints
Element | Left | Bottom | Right | Height |
Camera button | 20 | 13 | 20 | 51 |
Photo Library | 20 | 20 | 20 | 51 |
UINavigationControllerDelegate
and UIImagePickerControllerDelegate
protocols. Modify the declaration of the ViewController
class to resemble the following.
class ViewController: UIViewController,
UIImagePickerControllerDelegate,
UINavigationControllerDelegate
onCamera()
method in the ViewController.swift
file:
let imagePicker:UIImagePickerController = UIImagePickerController()
imagePicker.sourceType = UIImagePickerControllerSourceType.Camera
imagePicker.delegate = self
if UIDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad
{
imagePicker.modalPresentationStyle = UIModalPresentationStyle.Popover
self.presentViewController(imagePicker, animated: true, completion: nil)
let presentationController:UIPopoverPresentationController =
imagePicker.popoverPresentationController!
presentationController.permittedArrowDirections =
UIPopoverArrowDirection.Left
presentationController.sourceView = self.view
presentationController.sourceRect = cameraButton.frame
}
else
{
self.presentViewController(imagePicker, animated: true, completion: nil)
}
onPhotoLibrary()
method in the ViewController.swift
file:
let imagePicker:UIImagePickerController = UIImagePickerController()
imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
imagePicker.delegate = self
if UIDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad
{
imagePicker.modalPresentationStyle = UIModalPresentationStyle.Popover
self.presentViewController(imagePicker, animated: true, completion: nil)
let presentationController:UIPopoverPresentationController =
imagePicker.popoverPresentationController!
presentationController.permittedArrowDirections =
UIPopoverArrowDirection.Left
presentationController.sourceView = self.view
presentationController.sourceRect = cameraButton.frame
}
else
{
self.presentViewController(imagePicker,
animated: true,
completion: nil)
}
UIImagePickerControllerDelegate
methods in your view controller class.
ViewController.swift
file to implement the imagePickerControllerDidCancel(picker: UIImagePickerController)
delegate method:func imagePickerControllerDidCancel(picker: UIImagePickerController)
{
picker.dismissViewControllerAnimated(true, completion: nil)
}
ViewController.swift
file to implement the imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
delegate method:func imagePickerController(picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject])
{
let image:UIImage = info[UIImagePickerControllerOriginalImage] as!
UIImage
imageView.image = image
picker.dismissViewControllerAnimated(true, completion: nil)
}
viewDidLoad
method of your view controller class:
override func viewDidLoad() {
super.viewDidLoad()
let hasCamera = UIImagePickerController.isSourceTypeAvailable(
UIImagePickerControllerSourceType.Camera)
if hasCamera == false
{
cameraButton.hidden = true;
}
}