无法使用SwiftUI加载相机

时间:2019-12-17 11:22:13

标签: ios xcode camera uiimagepickercontroller swift5.1

我有2个按钮,一个按钮用于从图库中加载图像,另一个按钮用于从相机中加载图像(即拍照)。但是无论我尝试什么,我都会不断加载图库而不是相机。我一直在UIImagePickerController中使用以下代码(来自Google搜索):

//
//  ImagePicker.swift
//

import Foundation
import SwiftUI

class ImagePickerCoordinator: NSObject, UINavigationControllerDelegate,             
UIImagePickerControllerDelegate {

@Binding var isShown: Bool
@Binding var image: Image?

init(isShown: Binding<Bool>, image: Binding<Image?>) {
    _isShown = isShown
    _image = image
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

    let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
    image = Image(uiImage: uiImage)
    isShown = false

}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    isShown = false
}

}

struct ImagePicker: UIViewControllerRepresentable {

@Binding var isShown: Bool
@Binding var image: Image?

func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {

}

func makeCoordinator() -> ImagePickerCoordinator {
    return ImagePickerCoordinator(isShown: $isShown, image: $image)
}

func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
    let picker = UIImagePickerController()
    picker.delegate = context.coordinator
    return picker
}

}

struct CameraPicker: UIViewControllerRepresentable {

@Binding var isShown: Bool
@Binding var image: Image?

func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<CameraPicker>) {

}

func makeCoordinator() -> ImagePickerCoordinator {
    return ImagePickerCoordinator(isShown: $isShown, image: $image)
}

func makeUIViewController(context: UIViewControllerRepresentableContext<CameraPicker>) -> UIImagePickerController {
    let picker = UIImagePickerController()
    picker.sourceType = .camera
    picker.allowsEditing = true
    picker.delegate = context.coordinator
    return picker
}

}

struct CameraView: UIViewControllerRepresentable {

@Binding var isShown: Bool
@Binding var image: Image?

func makeCoordinator() -> CameraView.Coordinator {
    Coordinator(self)
}

func makeUIViewController(context: UIViewControllerRepresentableContext<CameraView>) -> UIViewController {
    let cameraViewController = UIImagePickerController()
    cameraViewController.delegate = context.coordinator
    cameraViewController.sourceType = .camera
    cameraViewController.allowsEditing = false
    return cameraViewController
}

func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<CameraView>) {

}

class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    var parent: CameraView

    init(_ cameraView: CameraView) {
        self.parent = cameraView
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
        parent.image = Image(uiImage: uiImage)
        parent.isShown = false
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        parent.isShown = false
    }
}
}

我基本上复制了ImagePicker来满足相机(CameraPicker)的需求。当我无法到达任何地方时,也尝试通过网络搜索查看“相机视图”。

我是新手,所以请告诉我是否有更好的方法。

要从相机获取图像:

//
//  PhotoCaptureView.swift


import SwiftUI

struct PhotoCaptureView: View {

    @Binding var showImagePicker: Bool
    @Binding var image: Image?

    var body: some View {
        CameraView(isShown: $showImagePicker, image: $image)
    }
}

#if DEBUG
struct PhotoCaptureView_Previews: PreviewProvider {
    static var previews: some View {
        PhotoCaptureView(showImagePicker: .constant(false), image: .constant(Image("")))
    }
}
#endif

要从图库中获取图片:

//
//  GalleryCapture.swift
//

import SwiftUI

struct GalleryCaptureView: View {

    @Binding var showImagePicker: Bool
    @Binding var image: Image?

    var body: some View {
        ImagePicker(isShown: $showImagePicker, image: $image)
    }
}

#if DEBUG
struct GalleryCaptureView_Previews: PreviewProvider {
    static var previews: some View {
        GalleryCaptureView(showImagePicker: .constant(false), image: .constant(Image("")))
    }
}
#endif

我的内容视图:

//
//  ContentView.swift
//

import SwiftUI

struct ContentView: View {

    @State private var showImagePicker: Bool = false
    @State private var image: Image? = nil

    // Function that converts an UIImage to Image
    func returnImage() -> Image
    {
        guard let img = image else {
            fatalError("Unable to load image")
        }
        return img
//        return Image(uiImage: img)
    }


    // Main Body
    var body: some View {
        NavigationView {
            VStack {
                VStack {
                    image?.resizable()
                        .frame(width: 299, height: 299)
                        .cornerRadius(6)
                }


//                returnImage()
//                    .resizable()
//                    .frame(width: 299, height: 299)
//                    .cornerRadius(6)
//                    .onTapGesture {
//                        self.showImagePicker = true
//                    }


                HStack {

                    Button(action: {self.showImagePicker.toggle()}) {
                        Image(systemName: "photo")
                            .font(.largeTitle)
                            .foregroundColor(.white)
                        Text("Gallery")
                                .foregroundColor(.white)
                            }.padding()
                            .background(Color.blue)
                            .cornerRadius(10)
                   .sheet(isPresented: self.$showImagePicker) {
                        GalleryCaptureView(showImagePicker: self.$showImagePicker, image: self.$image)
                   }

                    Button(action: {self.showImagePicker.toggle()}) {
                        Image(systemName: "camera")
                            .font(.largeTitle)
                            .foregroundColor(.white)
                        Text("Camera")
                        .foregroundColor(.white)
                    }.padding()
                    .background(Color.green)
                    .cornerRadius(10)
                    .sheet(isPresented: self.$showImagePicker) {
                        PhotoCaptureView(showImagePicker: self.$showImagePicker, image: self.$image)
                    }
                }
            }
            .navigationBarTitle("My first app")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

我想使用MLkit,所以可能还需要考虑使用UIImage而不是Image。

2 个答案:

答案 0 :(得分:1)

在按钮上,您必须将self.showImagePicker设置为true:

 var body: some View {
        NavigationView{

            VStack {

                image?.resizable().scaledToFit()

                Button("Open Camera"){
                    self.showImagePicker = true
                }.padding()
                .foregroundColor(Color.white)
                .background(Color.purple)
                .cornerRadius(10)
            }.sheet(isPresented: self.$showImagePicker){
                PhotoCaptureView(showImagePicker: self.$showImagePicker, image: self.$image)
            }

            .navigationBarTitle(Text("Camera"))
        }
    }

在makeUIViewController方法内,您只需要在picker.delegate = context.coordinator下面添加以下代码:

func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
    let picker = UIImagePickerController()
    picker.delegate = context.coordinator
    if !UIImagePickerController.isSourceTypeAvailable(.camera){
        picker.sourceType = .photoLibrary
    } else {
        picker.sourceType = .camera
    }
    return picker
}

注意:相机仅在您无法在模拟器中打开的真实设备中打开。

OR

将您的代码与这个很棒的code进行比较,它在我的身边工作

答案 1 :(得分:0)

最后证明是如此简单。我的错误是使用与我用于画廊的布尔值相同的布尔值。