Lots of apps need to deal with selecting or taking photos but in SwiftUI we’ll need to wrap UIKit’s UIImagePickerController with a SwiftUI view.
Wrapping UIImagePickerController in SwiftUI
UIImagePickerController has been available since iOS 2 and it supports both selecting photos from photo albums and taking new photos with a camera. If we would like to use an image picker in a SwiftUI view then the first step is wrapping this view controller with a SwiftUI view. UIViewControllerRepresentable protocol defines required methods for representing an UIViewController. We’ll provide a completion handler for passing back the selected image. We need to implement a coordinator which acts as a delegate for the UIImagePickerController. When the imagePickerController(_:didFinishPickingMediaWithInfo:) delegate method is called, then we can call the completion handler and handle the selected image in a SwiftUI view. As UIImagePickerController supports both the camera function and accessing existing photos, we’ll add a source type property for configuring which mode to use.
The ImagePicker can then be presented with the fullScreenCover view modifier. The presented state and the selected image is stored in the view’s view model. When the image picker is displayed and an image is selected, the completion handler is called and the selectedImage property is updated in the view model which in turn reloads the SwiftUI view.
Wrapping UIKit views with a SwiftUI view is fairly simple. The coordinator object is a perfect fit for handling delegate methods which UIKit views often provide. As we saw, adding a SwiftUI compatible image picker was pretty easy to do. Please check the full example project on GitHub.
SwiftUIImagePicker (Xcode 12.2)