【问题标题】:Can't load camera using SwiftUI无法使用 SwiftUI 加载相机
【发布时间】:2020-04-09 21:28:48
【问题描述】:

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

//
//  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)。当我无法到达任何地方时,还尝试了通过网络搜索查看相机视图。

我是 swift 新手,如果有更好的方法,请告诉我。

从相机获取图像:

//
//  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。

【问题讨论】:

    标签: ios xcode camera uiimagepickercontroller swift5.1


    【解决方案1】:

    最后竟然这么简单。我的错误是使用了与我用于图库的布尔值相同的布尔值。

    【讨论】:

    • 我犯了同样的错误,你的回答有帮助!!谢谢
    【解决方案2】:

    在按钮上,您必须像这样将 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
    }
    

    注意:相机只能在真机中打开,不能在模拟器中打开。

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

    【讨论】:

    • 我一定是做错了什么,因为它仍然只是在手机上打开画廊。 pastebin.com/Rg8mhu3r
    • 是的,这也是我尝试遵循的指南之一
    • 是的,我有。 self.showImagePicker.toggle() 不做同样的事情吗?
    猜你喜欢
    • 2021-06-11
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2016-04-18
    相关资源
    最近更新 更多