#SwiftUIでフォトライブラリを表示する
ボタンをタップして、フォトライブラリを表示します。
フォトライブラリで写真を選択すると、全画面に表示します。
Swiftを基礎から学ぶには
自著、工学社より発売中の「まるごと分かるSwiftプログラミング」をお勧めします。変数、関数、フロー制御構文、データ構造はもちろん、構造体からクロージャ、エクステンション、プロトコル、クロージャまでを基礎からわかりやすく解説しています。
環境
Swift 5.3
Xcode 12.0.1
macOS 10.15.7
フォトライブラリ
フォトライブラリをSwiftUIでラップした構造体を定義します。
ImagePicker.swift
import SwiftUI
struct ImagePicker: UIViewControllerRepresentable {
var sourceType: UIImagePickerController.SourceType = .photoLibrary
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = false
imagePicker.sourceType = sourceType
return imagePicker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
}
}
最初の画面
アプリの基本となる画面の構造体です。
ステート変数の基づいて、フォトライブラリをシート形式で表示します。
ContentView.swift
import SwiftUI
struct ContentView: View {
@State private var image = UIImage()
@State private var isShowPhotoLibrary = false
var body: some View {
VStack {
Image(uiImage: self.image)
Button(action: {
self.isShowPhotoLibrary = true
}, label: {
Text("Photo Library")
.padding()
})
}
.sheet(isPresented: $isShowPhotoLibrary, content: {
ImagePicker(sourceType: .photoLibrary)
})
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
フォトライブラリの写真を選択する
UIImagePickerControllerDelegate
プロトコルに準拠します。
ImagePicker.swift
import SwiftUI
struct ImagePicker: UIViewControllerRepresentable {
// MARK: - Working with UIViewControllerRepresentable
var sourceType: UIImagePickerController.SourceType = .photoLibrary
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = false
imagePicker.sourceType = sourceType
imagePicker.delegate = context.coordinator // Coordinater to adopt UIImagePickerControllerDelegate Protcol.
return imagePicker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
}
// MARK: - Using Coordinator to Adopt the UIImagePickerControllerDelegate Protocol
@Binding var selectedImage: UIImage
@Environment(\.presentationMode) private var presentationMode
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var parent: ImagePicker
init(_ parent: ImagePicker) {
self.parent = parent
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
parent.selectedImage = image
}
parent.presentationMode.wrappedValue.dismiss()
}
}
}
選択した写真を表示する
Image
ビューにモディファイアを追加します。
画面遷移するタイミングで、選択した写真をimage
プロパティに設定します。
ContentView.swift
struct ContentView: View {
@State private var image = UIImage()
@State private var isShowPhotoLibrary = false
var body: some View {
VStack {
Image(uiImage: self.image)
.resizable()
.scaledToFill()
.frame(minWidth: 0, maxWidth: .infinity)
.edgesIgnoringSafeArea(.all)
Button(action: {
self.isShowPhotoLibrary = true
}, label: {
Text("Photo Library")
.padding()
})
}
.sheet(isPresented: $isShowPhotoLibrary, content: {
ImagePicker(sourceType: .photoLibrary, selectedImage: self.$image)
})
}
}