갤러리의 사진을 가져오는 작업을 진행해보자.
구체적인 동작 과정을 적지않고 코드만 간단히 작성하려고 한다.
어떤 어플이든 필요할만한 기능이라 따로 코드로 가지고 있는 편이 좋아보인다.
import SwiftUI
struct ImagePicker: UIViewControllerRepresentable {
@Binding var image: UIImage?
@Environment(\.presentationMode) var mode
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIViewController(context: Context) -> some UIViewController {
let picker = UIImagePickerController()
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
}
}
extension ImagePicker {
class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
let parent: ImagePicker
init(_ parent: ImagePicker) {
self.parent = parent
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let image = info[.originalImage] as? UIImage else { return }
parent.image = image
parent.mode.wrappedValue.dismiss()
}
}
}
파일을 생성해주고 위 코드를 입력해준다.
ImagePicker를 구현하고 이용하기 위해
1. 3가지 State값
2. Image가 nil일 때의 처리
3. Image 할당
3가지 작업을 해주면 된다.
import SwiftUI
struct ImageViewTester: View {
@State var showImagePicker = false
@State var selectedUIImage: UIImage?
@State var image: Image?
func loadImage() {
guard let selectedImage = selectedUIImage else { return }
image = Image(uiImage: selectedImage)
}
var body: some View {
VStack(spacing: 20) {
if let image = image {
image
.resizable()
.clipShape(Circle())
.frame(width: 120, height: 120)
} else {
Image(systemName: "plus.viewfinder")
.resizable()
.foregroundColor(.blue)
.frame(width: 120, height: 120)
}
Button {
showImagePicker.toggle()
} label: {
Text("Image Picker")
}
.sheet(isPresented: $showImagePicker, onDismiss: {
loadImage()
}) {
ImagePicker(image: $selectedUIImage)
}
}
}
}
ImagePicker()를 이용하기 위한 binding값 showImagePicker와 가져온 이미지를 저장해주기 위해 selectedUIImage가 필요하다.
그리고 가져온 selectedUIImage는 UIImage 형식이라 Image로 변환을 해줄 때 loadImage() 함수를 이용해준다. 이 부분은 함수로 따로 작성안하고 onDismiss안에서 구현해줘도 무방할 것 같다.
Image는 기본적으로 nil이기 때문에 그대로 사용하면 error가 발생하고 nil 상태일 때는 다른 이미지로 표시하기 위해 if문을 이용했다.