应用程序打开画廊而不是相机 - XCode,SwiftUI

Posted

技术标签:

【中文标题】应用程序打开画廊而不是相机 - XCode,SwiftUI【英文标题】:Application opens gallery instead of camera - XCode, SwiftUI 【发布时间】:2020-07-01 19:03:05 【问题描述】:

我有一个应用程序,它的目标是打开相机拍照。然后将分析图片,但这会在稍后进行。我的问题在于,当 应该 打开相机的按钮时,而不是打开相机,画廊会打开,我可以在其中选择设备上已经存在的图像。

这是我的 AppDelegate.swift 文件

//
//  AppDelegate.swift
//  application2
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 



    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 
        // Override point for customization after application launch.
        return true
    

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration 
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) 
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    



这是我的 SceneDelegate.swift 文件

//
//  SceneDelegate.swift
//  application2
//

import UIKit
import SwiftUI

class SceneDelegate: UIResponder, UIWindowSceneDelegate 

    var window: UIWindow?


    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) 
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

        // Create the SwiftUI view that provides the window contents.
        let contentView = ContentView()

        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene 
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        
    

    func sceneDidDisconnect(_ scene: UIScene) 
        // Called as the scene is being released by the system.
        // This occurs shortly after the scene enters the background, or when its session is discarded.
        // Release any resources associated with this scene that can be re-created the next time the scene connects.
        // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
    

    func sceneDidBecomeActive(_ scene: UIScene) 
        // Called when the scene has moved from an inactive state to an active state.
        // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
    

    func sceneWillResignActive(_ scene: UIScene) 
        // Called when the scene will move from an active state to an inactive state.
        // This may occur due to temporary interruptions (ex. an incoming phone call).
    

    func sceneWillEnterForeground(_ scene: UIScene) 
        // Called as the scene transitions from the background to the foreground.
        // Use this method to undo the changes made on entering the background.
    

    func sceneDidEnterBackground(_ scene: UIScene) 
        // Called as the scene transitions from the foreground to the background.
        // Use this method to save data, release shared resources, and store enough scene-specific state information
        // to restore the scene back to its current state.
    



这是我的 ContentView.swift 文件

//
//  ContentView.swift
//  application2
//


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 

                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"))
        
    


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

这是我的 imagePicker.swift 文件

//
//  ImagePicker.swift
//  application2
//

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


这是我的 PhotoCaptureView.swift 文件

//
//  PhotoCaptureView.swift
//  application2
//


import SwiftUI

struct PhotoCaptureView: View 

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

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


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

#endif

感谢任何帮助。如果您认为我正在做的任何事情都是不必要的或可以做得更好,请随时告诉我。我是一名新的应用程序开发人员,经验不足。我拥有的大部分内容都是从这里和谷歌上的其他帖子中找到的。

【问题讨论】:

您没有包含 ImagePicker 的代码,而是再次粘贴了您的 ContentView 代码。 ImagePicker 可能是问题所在——我假设它是 UIImagePickerController 的包装器? @Adam 我的错误。我更新了帖子。 【参考方案1】:

我看到了在您的代码中包装 UIImagePickerController 的三种尝试:

    ImagePicker,将显示照片库,因为没有设置 sourceType。 CameraPicker,它似乎有一个复制粘贴错误,重复了它的 makeUIViewController 方法……如果可能,其中一种方法似乎将 sourceType 设置为相机。 CameraView,将其 sourceType 设置为相机。

我只看到你使用 ImagePicker,这是库之一。修复 CameraPicker 并改用它。

【讨论】:

你有什么办法可以给我一个关于如何解决这些错误的例子。我已经看了一段时间了,无法弄清楚。很抱歉,我是应用程序开发的新手。

以上是关于应用程序打开画廊而不是相机 - XCode,SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章

如何仅在 Swift 中访问从相机拍摄的图像,就像 iOS 中的画廊一样?

从相机或画廊获取全尺寸图片

带有画廊的意图 ACTION.IMAGE.CAPTURE

如何选择存储在 iOS 库中的最后一张图片

相机意图/活动 - 避免保存到画廊

文件输入 - 接受来自安卓相机或画廊的图像