【问题标题】:How to pick, display two images on two UIImageViews, and then upload these two chosen images to Firebase Database and Storage?如何选择,在两个 UIImageView 上显示两个图像,然后将这两个选择的图像上传到 Firebase 数据库和存储?
【发布时间】:2020-06-09 13:44:18
【问题描述】:

我想在一个 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()
    }

}

【问题讨论】:

    标签: ios swift firebase-storage uiimagepickercontroller


    【解决方案1】:

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

    而是创建和Array 以及从handleSelectWallpaperImageViewhandleSelectWallpaperImageView 中选择的两个图像,然后循环通过Array 并发送到Firebase

    查看更多信息:https://stackoverflow.com/a/49934285/1244403

    【讨论】:

    • 我真的不明白如何将它应用到我的代码中。您能否相对于我的代码更明确地解释一下。
    【解决方案2】:

    您可以在 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(_:) 方法中,您可以检查两个 imageView 的图像并上传它们,即您的 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

    【讨论】:

    • 不幸的是,它不断将同一图像从 profilePhoto 上传到 Firebase 数据库作为个人资料和壁纸
    • 基本上,您的逻辑是正确的,但需要一些更正,我在上面更新了自己的答案,它有效。但是,谢谢你,基本上你向我展示了我应该考虑解决这个问题的方式。
    • @Emtel 哦,是的,我只是展示了它是如何完成的,如果使用相应的 storageRef,它就可以正常工作。
    • 我更新了我的答案,使用各自的存储空间存储个人资料和壁纸图片。
    【解决方案3】:

    创建选项布尔变量

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-29
      • 2020-10-31
      • 2020-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-01
      相关资源
      最近更新 更多