SwiftUI calling the camera and calling the photo album are actually the same idea, and only one place needs to be modified. For album calls, please see “How to get images from the system album in SwiftUI”.
Let’s continue talking about camera calls. SwiftUI cannot obtain the camera by itself, so it has to rely on UIKit, so the header file is as follows:
import SwiftUI
importUIKit
Then, just like calling the photo album, we create an ImagePicker structure for us to obtain the system photo album content (so if we need to call the photo album and camera in one software, we only need to create an ImagePacker
structure):
struct ImagePicker: UIViewControllerRepresentable {
@Environment(\.presentationMode) private var presentationMode
let sourceType: UIImagePickerController.SourceType
let onImagePicked: (UIImage) -> Void
final class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
@Binding private var presentationMode: PresentationMode
private let sourceType: UIImagePickerController.SourceType
private let onImagePicked: (UIImage) -> Void
init(presentationMode: Binding<PresentationMode>,
sourceType: UIImagePickerController.SourceType,
onImagePicked: @escaping (UIImage) -> Void) {
_presentationMode = presentationMode
self.sourceType = sourceType
self.onImagePicked = onImagePicked
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
onImagePicked(uiImage)
presentationMode.dismiss()
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
presentationMode.dismiss()
}
}
func makeCoordinator() -> Coordinator {
return Coordinator(presentationMode: presentationMode,
sourceType: sourceType,
onImagePicked: onImagePicked)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.sourceType = sourceType
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController,
context: UIViewControllerRepresentableContext<ImagePicker>) {
}
}
The difference is when calling, when calling the album, we use .photoLibrary
for the sourceType
part. Here we only need to change it to .camera
, as follows:
struct ContentView: View {
@State private var showCameraPicker = false
//The image here is used to place the photos that will be taken later.
@State private var image: UIImage = UIImage()
var body: some View {
List{
Button(action: {
showCameraPicker = true
}, label: {
Text("Camera")
})
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
}
.sheet(isPresented: $showCameraPicker,
content: {
ImagePicker(sourceType: .camera) { image in
self.image = image
}
})
}
}
This way we can call the system camera.
I hope these will help someone in need~