如何从 SwiftUI 中的图库中选择图像

Posted

技术标签:

【中文标题】如何从 SwiftUI 中的图库中选择图像【英文标题】:How to pick image from gallery in SwiftUI 【发布时间】:2019-07-19 10:17:23 【问题描述】:

我尝试制作一个符合 UIViewRepresentable 并实现 makeUIView 和 updateUIView 的 SwiftUI 类。 但无法完成。这是代码:

代码:

struct ImagePicker : UIViewRepresentable 

@Binding var image: UIImage

class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate 

    @Binding var image: UIImage

    init(image: Binding<UIImage>) 
        $image = image
    

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


        if let possibleImage = info[.editedImage] as? UIImage 
            image = possibleImage
         else if let possibleImage = info[.originalImage] as? UIImage 
            image = possibleImage
         else 

        
    


func makeCoordinator() -> Coordinator 
    return Coordinator(image: $image)


func makeUIView(context: UIViewRepresentableContext<ImagePicker>) -> UIImageView 
    let imageview = UIImageView()
    let picker = UIImagePickerController()
    picker.delegate = context.coordinator
    return imageview


func updateUIView(_ uiView: UIImageView,
                  context: UIViewRepresentableContext<ImagePicker>) 
    uiView.image = image



我尝试使用 imagePicker 作为控件但无法使用。

【问题讨论】:

一个工作版本的UIImagePickerController。查看您的代码,您已经接近了。但。首先,“它不起作用”是什么意思。 (更多细节会有所帮助。)接下来,我的版本基于对这个问题的公认答案:***.com/questions/56515871/… 但最后 - 抱歉大喊大叫 - 我的版本,那个版本,我猜你的版本都坏了在三天前发布的 beta 4 中。你运行的是什么版本的? 感谢您的回复。你的答案对我有用。 【参考方案1】:

我在这里使用presentationMode 来检查它是否呈现的视图?

通过使用这个你可以dismiss()UIImagePickerController

SwiftUI 预览示例代码:

import SwiftUI

struct ContentView: View 

    @State var isShowPicker: Bool = false
    @State var image: Image? = Image("placeholder")

    var body: some View 
        NavigationView 
            ZStack 
                VStack 
                    image?
                        .resizable()
                        .scaledToFit()
                        .frame(height: 320)
                    Button(action: 
                        withAnimation 
                            self.isShowPicker.toggle()
                        
                    ) 
                        Image(systemName: "photo")
                            .font(.headline)
                        Text("IMPORT").font(.headline)
                    .foregroundColor(.black)
                    Spacer()
                
            
            .sheet(isPresented: $isShowPicker) 
                ImagePicker(image: self.$image)
            
            .navigationBarTitle("Pick Image")
        
    



struct ImagePicker: UIViewControllerRepresentable 

    @Environment(\.presentationMode)
    var presentationMode

    @Binding var image: Image?

    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate 

        @Binding var presentationMode: PresentationMode
        @Binding var image: Image?

        init(presentationMode: Binding<PresentationMode>, image: Binding<Image?>) 
            _presentationMode = presentationMode
            _image = image
        

        func imagePickerController(_ picker: UIImagePickerController,
                                   didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) 
            let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
            image = Image(uiImage: uiImage)
            presentationMode.dismiss()

        

        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) 
            presentationMode.dismiss()
        

    

    func makeCoordinator() -> Coordinator 
        return Coordinator(presentationMode: presentationMode, image: $image)
    

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

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

    




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

【讨论】:

用户选择图片后,父类中的图片变量不填充。【参考方案2】:

请试试这个

代码:

import SwiftUI

struct OpenGallary: UIViewControllerRepresentable 

    let isShown: Binding<Bool>
    let image: Binding<Image?>

    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate 

        let isShown: Binding<Bool>
        let image: Binding<Image?>

        init(isShown: Binding<Bool>, image: Binding<Image?>) 
            self.isShown = isShown
            self.image = image
        

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

        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) 
            isShown.wrappedValue = false
        

    

    func makeCoordinator() -> Coordinator 
        return Coordinator(isShown: isShown, image: image)
    

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

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

    

选择器显示在视图的正上方,没有过渡 所选图像出现时没有任何类型的动画,并替换了显示图像选择器按钮

之后创建显示视图,您可以在其中调用显示此 imagePicker

struct ContentView: View 

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

    var body: some View 
        ZStack 
            VStack 
                Button(action: 
                    withAnimation 
                        self.showImagePicker.toggle()
                    
                ) 
                    Text("Show image picker")
                
                image?.resizable().frame(width: 100, height: 100)
            
            if (showImagePicker) 
                OpenGallary(isShown: $showImagePicker, image: $image)
            
        
    

【讨论】:

以上是关于如何从 SwiftUI 中的图库中选择图像的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ImageView 中显示图库中的图像?

如何从图库中加载图像视图中的图像?

Phonegap - 从图库中选择图像

如何在 IONIC 3 中从图库中获取或选择图像

如何从 iPhone 的图库中选择图像的路径?

从图库中选择图像后如何打开下一个视图控制器(swift)