• 赚钱入口【需求资源】限时招募流量主、渠道主,站长合作;【合作模式】CPS长期分成,一次推广永久有收益。主动打款,不扣量;

如何在SwiftUI中访问照片库和使用相机

iOS rin, seun 10个月前 (06-17) 257次浏览 0个评论

之前,我们探讨了的用法,UIViewRepresentable并向您展示了如何将UITextView集成到SwiftUI项目中。虽然可以使用该UIViewRepresentable协议包装UIKit视图,但是视图控制器又如何呢?您可能需要在应用程序中使用相机或访问用户的照片库。那么,如何使用将UIImagePickerController类集成到您的SwiftUI视图中呢?

在本教程中,我们将引导您使用UIViewControllerRepresentable协议进行集成。它与UIViewRepresentable协议非常相似,但是UIViewControllerRepresentable设计用于包装UIKit视图控制器。如果您已经阅读教程UIViewRepresentable,所有的程序,我们要讨论的应该是你非常熟悉。

使用UIViewControllerRepresentable

基本上,要集成UIImagePickerController到SwiftUI项目中,您可以使用UIViewControllerRepresentable协议包装控制器并实现所需的方法:

struct ImagePicker: UIViewControllerRepresentable {
    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
 
        // Return an instance of UIImagePickerController
    }
 
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
 
    }
}

 

该协议有两种需要遵循的方法。初始化makeUIViewController时调用此方法ImagePicker。在该方法中,您需要实例化UIImagePickerController并配置其初始状态。对于该updateUIViewController方法,当应用程序的状态发生变化时会调用该方法,这会影响图像选择器。您可以实现该方法来更新图像选择器控制器的配置。这是完全可选的。如果没有要更新的内容,则可以将该方法留空。

在SwiftUI中创建ImagePicker

与往常一样,我喜欢通过构建演示来说明API。让我们使用“ 单一视图应用程序”模板创建一个名为SwiftUIImagePicker的新项目。只要确保您为用户界面选项选择SwiftUI

接下来,我们将为创建一个新文件ImagePicker。在项目导航器中右键单击SwiftUIImagePacker文件夹,然后选择New File…。选择“ 快速文件”模板。首先,我们需要导入UIKit和SwiftUI框架:

import UIKit
import SwiftUI

接下来,创建ImagePicker结构并采用UIViewControllerRepresentable协议:

struct ImagePicker: UIViewControllerRepresentable {
    var sourceType: UIImagePickerController.SourceType = .photoLibrary
    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) –> UIImagePickerController {
        let imagePicker = UIImagePickerController()
        imagePicker.allowsEditing = false
        imagePicker.sourceType = sourceType
        return imagePicker
    }
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
    }
}

UIImagePickerController课程使您可以访问照片库并使用内置相机。在上面的代码中,我们sourceType为此声明了一个变量。默认情况下,它设置为打开用户的照片库。在该makeUIViewController方法中,我们实例化的实例UIImagePickerController并配置其源类型。

使用ImagePicker在SwiftUI视图中加载照片库

现在,我们已经创建了ImagePicker,让我们看看如何在SwiftUI视图中使用它。切换到ContentView.swift并更新ContentView结构,如下所示:

我们有一个状态变量来控制照片库的外观,而另一个状态变量用于所选图像。默认情况下,所选图像设置为空白图像。在视图中,我们有一个按钮来更改状态isShowPhotoLibrary。如果正确编写了代码,则预览中应该会看到类似以下内容:

如何在SwiftUI中访问照片库和使用相机

要使用ImagePicker加载照片库,请按如下所示将.sheet修饰符附加到VStack

.sheet(isPresented: $isShowPhotoLibrary) {
ImagePicker(sourceType: .photoLibrary)
}

在闭合中,我们创建ImagePicker并在用户点击照片库按钮时显示照片库。在预览画布中运行该应用程序。您应该可以打开照片库。

如何在SwiftUI中访问照片库和使用相机

使用协调器采用UIImagePickerControllerDelegate协议

目前,内容视图对所选图像一无所知。当您在图库中选择照片时,该应用程序仅关闭照片库视图并返回主屏幕。

如果您以前使用UIImagePickerController过,则知道您必须采用两个委托:UIImagePickerControllerDelegateUINavigationControllerDelegate为了与图像选择器控制器进行交互。当用户从照片库中选择照片时,将imagePickerController(_:didFinishPickingMediaWithInfo:)调用委托的方法。

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

通过实现该方法,我们可以从该方法的参数中获取选定的照片。要采用中的协议ImagePicker,我们必须实现该makeCoordinator方法并提供一个Coordinator实例。这Coordinator充当了控制器的委托和SwiftUI之间的桥梁。

现在回到ImagePicker.swift并声明两个这样的变量:

@Binding var selectedImage: UIImage
@Environment(\.presentationMode) private var presentationMode

顾名思义,该selectedImage变量用于存储选定的图像。用户选择照片后,我们需要关闭照片库。为此,该presentationMode变量就是为此目的而设计的。稍后,我们可以调用presentationMode.wrappedValue.dismiss()以消除视图。

接下来,像这样Coordinator在内部创建类ImagePicker

final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
 
    var parent: ImagePicker
 
    init(_ parent: ImagePicker) {
        self.parent = parent
    }
 
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
 
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            parent.selectedImage = image
        }
 
        parent.presentationMode.wrappedValue.dismiss()
    }
}

 

Coordinator类采用UIImagePickerControllerDelegate的协议和实现imagePickerController(_:didFinishPickingMediaWithInfo:)委托的方法。选择图像时将调用该方法。在该方法中,我们检索选定的图像,然后关闭照片库。

init方法采用的实例ImagePicker,以便我们可以将选定的图像传递给它,然后使用它presentationMode来消除视图。

现在我们已经准备好了Coordinator类,下一步是创建makeCoordinator方法并返回的实例Coordinator

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

最后,我们需要将协调人指定为的代表UIImagePickerController。在该makeUIViewController方法中,插入以下代码行:

imagePicker.delegate = context.coordinator

在测试更改之前,请切换到ContentView.swift并更新.sheet修饰符中的代码:

.sheet(isPresented: $isShowPhotoLibrary) {
    ImagePicker(sourceType: .photoLibrary, selectedImage: self.$image)
}

我们必须传递的绑定,image以便ImagePicker可以传递用户选择的图像进行显示。现在,在模拟器或预览画布中运行该应用程序。该应用现在可以显示所选图像。

如何在SwiftUI中访问照片库和使用相机

在SwiftUI中使用相机

ImagePicker具有足够的灵活性,支持内置摄像头。如果你想打开相机,可拍摄照片的SwiftUI的应用程序,你可以改变sourceType.photoLibray,以.camera这样的:

ImagePicker(sourceType: .camera, selectedImage: self.$image)

在iOS中,用户必须明确授予每个应用访问相机的权限。除了上述更改之外,您还需要编辑Info.plist文件并指定应用程序需要使用内置摄像头的原因。

如何在SwiftUI中访问照片库和使用相机

您无法使用模拟器测试此选项。但是,如果您拥有iPhone,则可以将应用程序部署到设备上并进行尝试。

编者注:如果您想了解有关构建全屏摄像头的更多信息,可以查看本教程

摘要

在本教程中,我向您介绍了该UIViewControllerRepresentable协议,该协议充当UIKit视图和SwiftUI视图中的视图控制器之间的桥梁。通过使用该协议,我们将其集成UIImagePickerController到一个SwiftUI项目中,从而允许应用程序访问照片库和设备的相机。

SwiftUI仍然是一个非常新的框架,因此并非所有UIKit组件都在该框架中可用。如果您在SwiftUI中找不到本机UI组件,则可以应用此技术将UIKit组件引入SwiftUI项目。

作为参考,您可以在GitHub上下载完整项目

喜欢 (0)

您必须 登录 才能发表评论!