How to open the ImagePicker in SwiftUI?

后端 未结 8 1285
生来不讨喜
生来不讨喜 2020-11-29 23:53

I need to open the ImagePicker in my app using SwiftUI, how can I do that?

I thought about using the UIImagePickerController, but I don\'t know how to do that in Swi

8条回答
  •  一生所求
    2020-11-30 00:26

    Based on @user:2890168 I made a version that:

    • retrieves UIImage instead of Image
    • use .sheet to present the ImagePicker.
    • shows ActionSheet to help users to remove or change the image.

    struct LibraryImage: View {
    
        @State var showAction: Bool = false
        @State var showImagePicker: Bool = false
    
        @State var uiImage: UIImage? = nil
    
        var sheet: ActionSheet {
            ActionSheet(
                title: Text("Action"),
                message: Text("Quotemark"),
                buttons: [
                    .default(Text("Change"), action: {
                        self.showAction = false
                        self.showImagePicker = true
                    }),
                    .cancel(Text("Close"), action: {
                        self.showAction = false
                    }),
                    .destructive(Text("Remove"), action: {
                        self.showAction = false
                        self.uiImage = nil
                    })
                ])
    
        }
    
    
        var body: some View {
            VStack {
    
                if (uiImage == nil) {
                    Image(systemName: "camera.on.rectangle")
                        .accentColor(Color.App.purple)
                        .background(
                            Color.App.gray
                                .frame(width: 100, height: 100)
                                .cornerRadius(6))
                        .onTapGesture {
                            self.showImagePicker = true
                        }
                } else {
                    Image(uiImage: uiImage!)
                        .resizable()
                        .frame(width: 100, height: 100)
                        .cornerRadius(6)
                        .onTapGesture {
                            self.showAction = true
                        }
                }
    
            }
    
            .sheet(isPresented: $showImagePicker, onDismiss: {
                self.showImagePicker = false
            }, content: {
                ImagePicker(isShown: self.$showImagePicker, uiImage: self.$uiImage)
            })
    
            .actionSheet(isPresented: $showAction) {
                sheet
            }
        }
    }
    

    The default body of LibraryImage is an Image that shows a camera icon that is tappable by the users.

    On tap event, the image picker is shown with a sheet modifier. After the image selection, the LibraryImage body is recomputed and now shows the Image defined in else statement (because uiImage property now contains the image picked by the user).

    Now, on tap event the ActionSheet is shown.

    The edited image picker:

    struct ImagePicker: UIViewControllerRepresentable {
    
        @Binding var isShown: Bool
        @Binding var uiImage: UIImage?
    
        class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    
            @Binding var isShown: Bool
            @Binding var uiImage: UIImage?
    
            init(isShown: Binding, uiImage: Binding) {
                _isShown = isShown
                _uiImage = uiImage
            }
    
            func imagePickerController(_ picker: UIImagePickerController,
                                       didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
                let imagePicked = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
                uiImage = imagePicked
                isShown = false
            }
    
            func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
                isShown = false
            }
    
        }
    
        func makeCoordinator() -> Coordinator {
            return Coordinator(isShown: $isShown, uiImage: $uiImage)
        }
    
        func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIImagePickerController {
            let picker = UIImagePickerController()
            picker.delegate = context.coordinator
            return picker
        }
    
        func updateUIViewController(_ uiViewController: UIImagePickerController,
                                    context: UIViewControllerRepresentableContext) {
    
        }
    
    }
    

    default behaviour:

提交回复
热议问题