Home Swift UNIX C Assembly Go Web MCU Research Non-Tech

How to call the camera in SwiftUI

2021-12-10 | Swift | #Words: 695 | 中文原版

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~