如何在SwiftUI中从图库中选取图像

t3psigkw  于 2023-01-08  发布在  Swift
关注(0)|答案(3)|浏览(364)

我尝试创建一个SwiftUI类,它符合UIViewRepresentable并实现makeUIView和updateUIView。但无法完成它。以下是代码:
代码:

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作为控件,但无法使用。

mzsu5hc0

mzsu5hc01#

我在这里使用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()
        }
    }
}
8hhllhi2

8hhllhi22#

请试试这个
代码:

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

    }
}

选择器显示在视图的正上方,如果没有转换,则所选图像将不带任何动画,并替换"显示图像选择器"按钮
然后创建显示视图,在其中可以调用show this 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)
            }
        }
    }
}
b5lpy0ml

b5lpy0ml3#

SwiftUI终于在iOS 16中获得了自己的原生照片选择器视图。PhotosPicker视图支持PHPickerViewController提供的所有常见功能,如单选多选、资产类型过滤和相册切换。

import SwiftUI
import PhotosUI

struct ContentView: View {
    
    //MARK: - Properties
    //@State private var selectedItem: [PhotosPickerItem] = [PhotosPickerItem]() // use to select multiple images from gallery
    @State private var selectedItem: PhotosPickerItem? = nil
    @State private var selectedImageData: Data? = nil
    
    //MARK: - Body
    
    var body: some View {
        VStack {
                PhotosPicker(
                    selection: $selectedItem,
                   // maxSelectionCount: 2, //set max selection from gallery
                    matching: .images,
                    photoLibrary: .shared()
                ) {
                    Text("Choose Photos from Gallery")
                        .frame(width: 350, height: 50)
                        .background(Capsule().stroke(lineWidth: 2))
                }
                .onChange(of: selectedItem) { newValue in
                    Task { // Incase of multiple selection newValue is of array type
                        if let data = try? await newValue?.loadTransferable(type: Data.self) {
                            selectedImageData = data
                        }
                    }
                }
            if let selectedImageData, let uiImage = UIImage(data: selectedImageData) {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFit()
                    .frame(width: 250, height: 250)
                    .overlay(
                        RoundedRectangle(cornerRadius: 16).stroke(Color.yellow, lineWidth: 8)
                    )
            }
        }
        .padding()
    }
}

样品ss

第一个c0d1x第一个c1d1x第一个c2d1x

相关问题