🙌
SwiftUIでUIImagePickerControllerを使う
カメラやライブラリから写真を取り出すUIImagePickerController
をSwiftUIで使うことが多いのでコピペで使えるように。
環境
- Xcode 12.4
- iOS 14.4
ImagePickerView.swift
UIImagePickerController
はUIKit
のコンポーネントなのでUIViewControllerRepresentable
を使ってSwiftUIから呼び出せるようにする。
ImagePickerView.swift
import SwiftUI
struct ImagePickerView: UIViewControllerRepresentable {
typealias UIViewControllerType = UIImagePickerController
@Environment(\.presentationMode) var presentationMode
@Binding var image: UIImage?
enum SourceType {
case camera
case library
}
var sourceType: SourceType
var allowsEditing: Bool = false
class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
let parent: ImagePickerView
init(_ parent: ImagePickerView) {
self.parent = parent
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
if let image = info[.editedImage] as? UIImage {
parent.image = image
} else if let image = info[.originalImage] as? UIImage {
parent.image = image
}
parent.presentationMode.wrappedValue.dismiss()
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIViewController(context: Context) -> UIImagePickerController {
let viewController = UIImagePickerController()
viewController.delegate = context.coordinator
switch sourceType {
case .camera:
viewController.sourceType = UIImagePickerController.SourceType.camera
case .library:
viewController.sourceType = UIImagePickerController.SourceType.photoLibrary
}
viewController.allowsEditing = allowsEditing
return viewController
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {
}
}
コードの説明は割愛、ポイントのみ
- 引数の
SourceType
でcamera
とlibrary
を選択する- cameraを使うときは
Info.plist
にNSCameraUsageDescription
を追加すること
- cameraを使うときは
-
allowsEditing
でUIImagePickerController
が提供している編集機能が利用可能
利用
利用するコードの例はこちら。
ContentView.swift
import SwiftUI
struct ContentView: View {
@State var showingPicker = false
@State var image: UIImage?
var body: some View {
VStack {
if let image = image {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
}
Text("Image")
.onTapGesture {
showingPicker.toggle()
}
}
.sheet(isPresented: $showingPicker) {
ImagePickerView(image: $image, sourceType: .library)
}
}
}
カメラを使い、編集を有効にする場合の呼び出し例はこちら
ImagePickerView(image: $image, sourceType: .camera, allowsEditing: true)
備考
UIImagePickerControllerからフォトライブラリへのアクセスはiOS14
でdeprecatedになりました。
UIImagePickerController.SourceType.photoLibrary
Specifies the device’s photo library as the source for the image picker controller.
Deprecated
Use PHPickerViewController instead.
iOS14以降をターゲットにする場合はPHPickerViewController
を使用した方が良いようです。
参考
Overview
Use a UIViewControllerRepresentable instance to create and manage a UIViewController object in your SwiftUI interface.
Discussion