如何在两个 UIImageView 上选择、显示两个图像,然后将这两个选择的图像上传到 Firebase 数据库和存储?

How to pick, display two images on two UIImageViews, and then upload these two chosen images to Firebase Database and Storage?

我想在一个 ViewController 的两个 imageView 上选取两个不同的图像,显​​示它们,然后在按下按钮后将选取的图像保存到 firebase 数据库并存储给其特定用户。我的代码只能上传一张挑选的图片,不能上传两张不同的图片,我知道 UIImagePickerController 部分有问题,但我该如何解决它。 viewController 的完整代码如下。请帮忙!!

override func viewDidLoad() {
        super.viewDidLoad()

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(SettingProfileViewController.handleSelectProfileImageView(sender:)))
        profilePhoto.addGestureRecognizer(tapGesture)
        profilePhoto.isUserInteractionEnabled = true

        let wallTapGesture = UITapGestureRecognizer(target: self, action: #selector(SettingProfileViewController.handleSelectWallpaperImageView(sender:)))
        wallpaperPhoto.addGestureRecognizer(wallTapGesture)
        wallpaperPhoto.isUserInteractionEnabled = true

        profilePhoto.layer.cornerRadius = 60
        profilePhoto.clipsToBounds = true

    }

    weak var activeImageView:UIImageView? = nil


    @objc func handleSelectWallpaperImageView(sender: UIGestureRecognizer){
        guard let sendingImageView = sender.view as? UIImageView else {
            print("Ooops, received this gesture not from an ImageView")
            return
        }
        activeImageView = sendingImageView
        let actionSheet = UIAlertController(title: "New Photo", message: nil, preferredStyle: .actionSheet)
        actionSheet.addAction(UIAlertAction(title: "Камера", style: .default, handler: { action in
            self.showCamera()
        }))

        actionSheet.addAction(UIAlertAction(title: "Альбом ", style: .default, handler: {action in
            self.showAlbum()
        }))

        actionSheet.addAction(UIAlertAction(title: "Отмена", style: .cancel, handler: nil))
        self.present(actionSheet, animated: true, completion: nil)
    }


    @objc func handleSelectProfileImageView(sender: UIGestureRecognizer){
        guard let sendingImageView = sender.view as? UIImageView else {
            print("Ooops, received this gesture not from an ImageView")
            return
        }
        activeImageView = sendingImageView

        let actionSheet = UIAlertController(title: "New Photo", message: nil, preferredStyle: .actionSheet)
        actionSheet.addAction(UIAlertAction(title: "Камера", style: .default, handler: { action in
            self.showCamera()

        }))

        actionSheet.addAction(UIAlertAction(title: "Альбом ", style: .default, handler: {action in
            self.showAlbum()

        }))

        actionSheet.addAction(UIAlertAction(title: "Отмена", style: .cancel, handler: nil))
        self.present(actionSheet, animated: true, completion: nil)
    }


    func showCamera() {

        let cameraPicker = UIImagePickerController()
        cameraPicker.delegate = self
        cameraPicker.sourceType = .camera

        present(cameraPicker, animated: true, completion: nil)
    }

    func showAlbum(){
           let cameraPicker = UIImagePickerController()
        cameraPicker.delegate = self 
           cameraPicker.sourceType = .photoLibrary

           present(cameraPicker, animated: true, completion: nil)
       }




    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        dismiss(animated: true, completion: nil)
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage{
//             selectedImage = image
            activeImageView?.image = image
//            currentImage = image
        }
    }



    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
         dismiss(animated: true, completion: nil)
    }


    ///для того чтобы загруженные фото, отображались на ProfileViewController
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "profileVC" {
            let destination = segue.destination as! ProfileViewController
            destination.wImage = activeImageView?.image


        }
    }




    @IBAction func saveTapped(_ sender: Any) {

        let db = Firestore.firestore()
        let did = Auth.auth().currentUser!.uid

        let storageRef = Storage.storage().reference(forURL: "gs://crut-6c67c.appspot.com").child("profile_Image").child(did)
        if let pImage = self.activeImageView?.image, let imageData = pImage.jpegData(compressionQuality: 0.1) {
            storageRef.putData(imageData, metadata: nil, completion: {(metadata, Error) in
                if Error != nil, metadata != nil {
                    return
                }

                storageRef.downloadURL { (url: URL?,error: Error?) in
                    if let profileImageUrl = url?.absoluteString{
                        db.collection("suppliers").document("ip").collection("ipinfo").document(did).setData(["Profile Image":profileImageUrl], merge: true)
                    }
                }
            })
        }


        let storyBoard: UIStoryboard = UIStoryboard(name: "Profile", bundle: nil)
        let profileViewController = storyBoard.instantiateViewController(identifier:profile.Storyboard.profileViewController) as? ProfileViewController
        self.view.window?.rootViewController = profileViewController
        self.view.window?.makeKeyAndVisible()
    }

}

我希望你在 activeImageView 上保存最后选择的图像并将其传递给 Firebase,因此只上传了一张图像。

而是创建 Array 以及从 handleSelectWallpaperImageViewhandleSelectWallpaperImageView 中选择的图像,然后遍历 Array 并发送到 Firebase

检查此以获取更多信息:

您可以在 viewController 中创建一个实例变量,即

private var isProfilePhotoSelecting = true

当用户点击 handleSelectProfileImageView 方法中的 profileImageView 时,将 isProfilePhotoSelecting 设置为 true 即

@objc func handleSelectProfileImageView(sender: UIGestureRecognizer){
        guard let sendingImageView = sender.view as? UIImageView else {
            print("Ooops, received this gesture not from an ImageView")
            return
        }

        // Updated the image under consideration
        isProfilePhotoSelecting = true

        let actionSheet = UIAlertController(title: "New Photo", message: nil, preferredStyle: .actionSheet)
        actionSheet.addAction(UIAlertAction(title: "Камера", style: .default, handler: { action in
            self.showCamera()

        }))

        actionSheet.addAction(UIAlertAction(title: "Альбом ", style: .default, handler: {action in
            self.showAlbum()

        }))

        actionSheet.addAction(UIAlertAction(title: "Отмена", style: .cancel, handler: nil))
        self.present(actionSheet, animated: true, completion: nil)
    }

并且在 wallpaperImageView 上点击 handleSelectWallpaperImageView 方法将 isProfilePhotoSelecting 设置为 false,即

@objc func handleSelectWallpaperImageView(sender: UIGestureRecognizer){
        guard let sendingImageView = sender.view as? UIImageView else {
            print("Ooops, received this gesture not from an ImageView")
            return
        }
        // Updated the image under consideration
        isProfilePhotoSelecting = false

        let actionSheet = UIAlertController(title: "New Photo", message: nil, preferredStyle: .actionSheet)
        actionSheet.addAction(UIAlertAction(title: "Камера", style: .default, handler: { action in
            self.showCamera()
        }))

        actionSheet.addAction(UIAlertAction(title: "Альбом ", style: .default, handler: {action in
            self.showAlbum()
        }))

        actionSheet.addAction(UIAlertAction(title: "Отмена", style: .cancel, handler: nil))
        self.present(actionSheet, animated: true, completion: nil)
    }

然后将您的 imagePickerDelegate 更新为:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            if isProfilePhotoSelecting {
                profilePhoto.image = image
            } else {
                wallpaperPhoto.image = image
            }
        }
        dismiss(animated: true, completion: nil)
    }

这将帮助您将两张图片设置为各自的 imageView。然后在 saveTapped(_:) 方法中,您可以检查两个 imageViews 的图像并上传它们,即您的 saveTapped() 方法应该如下所示

@IBAction func saveTapped(_ sender: Any) {

    let db = Firestore.firestore()
    let did = Auth.auth().currentUser!.uid

    let storageRef = Storage.storage().reference(forURL: "gs://crut-6c67c.appspot.com")
    if let profileImage = self.profilePhoto.image, let imageData = profileImage.jpegData(compressionQuality: 0.1) {
        let profileStorage = storageRef.child("profile_Image").child(did)
        profileStorage.putData(imageData, metadata: nil, completion: {(metadata, Error) in
            if Error != nil, metadata != nil {
                return
            }

            profileStorage.downloadURL { (url: URL?,error: Error?) in
                if let profileImageUrl = url?.absoluteString {
                    db.collection("suppliers").document("ip").collection("ipinfo").document(did).setData(["Profile Image":profileImageUrl], merge: true)
                }
            }
        })
    }



    if let wallpaperImage = self.wallpaperPhoto.image, let imageData = wallpaperImage.jpegData(compressionQuality: 0.1) {
        let wallpaperStorage = storageRef.child("wallpaper_Image").child(did)
        wallpaperStorage.putData(imageData, metadata: nil, completion: {(metadata, Error) in
            if Error != nil, metadata != nil {
                return
            }

            wallpaperStorage.downloadURL { (url: URL?,error: Error?) in
                if let wallpaperImageUrl = url?.absoluteString {

                    // Do your stuff with wallpaper image url here

                }
            }
        })
    }


    let storyBoard: UIStoryboard = UIStoryboard(name: "Profile", bundle: nil)
    let profileViewController = storyBoard.instantiateViewController(identifier:profile.Storyboard.profileViewController) as? ProfileViewController
    self.view.window?.rootViewController = profileViewController
    self.view.window?.makeKeyAndVisible()
}

注意:这不会像等待图片上传那样等待图片上传。但是,如果您想等到图像上传完成然后移动到 ProfileViewController,这取决于您的用例,您可以为此目的使用 DispatchGroup

已创建选项布尔变量

var isProfilePhotoSelecting:Bool?

@objc func handleSelectWallpaperImageView(sender: UIGestureRecognizer){
isProfilePhotoSelecting = false
/// 
other code
}
@objc func handleSelectProfileImageView(sender: UIGestureRecognizer){
isProfilePhotoSelecting = true
/// 
other code
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        dismiss(animated: true, completion: nil)
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage{

            if isProfilePhotoSelecting == true {
                profilePhoto.image = image
            }else {
                wallpaperPhoto.image = image
            }

        }
    }

在 saveTapped 中需要添加对每个选定图像及其各自数据库的存储引用。

@IBAction func saveTapped(_ sender: Any) {

        let db = Firestore.firestore()
        let did = Auth.auth().currentUser!.uid

        let storageRef = Storage.storage().reference(forURL: "gs://crut-6c67c.appspot.com").child("profile_Image").child(did)
        if let profileImage = self.profilePhoto.image, let imageData = profileImage.jpegData(compressionQuality: 0.1){
            storageRef.putData(imageData, metadata: nil, completion: {(metadata, Error) in
                if Error != nil, metadata != nil {
                    return
                }
                storageRef.downloadURL { (url: URL?, error: Error?) in
                    if let profileImageUrl = url?.absoluteString {
                        db.collection("suppliers").document("ip").collection("ipinfo").document(did).setData(["Profile Image":profileImageUrl], merge: true)
                    }
                }
            })
        }

        let wallStoreRef = Storage.storage().reference(forURL: "gs://crut-6c67c.appspot.com").child("Wallpaper_Image").child(did)
        if let wallpaperImage = self.wallpaperPhoto.image, let imageData = wallpaperImage.jpegData(compressionQuality: 0.1) {
            wallStoreRef.putData(imageData, metadata: nil, completion: {(metadata, Error) in
                if Error != nil, metadata != nil {
                    return
                }

                wallStoreRef.downloadURL { (url: URL?,error: Error?) in
                    if let wallpaperImageUrl = url?.absoluteString {
                        // Do your stuff with wallpaper image url here
                    db.collection("suppliers").document("ip").collection("ipinfo").document(did).setData(["Wallpaper Image":wallpaperImageUrl], merge: true)



                    }
                }
            })
        }