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

时间:2020-02-25 18:35:37

标签: ios swift firebase-storage uiimagepickercontroller

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

}

3 个答案:

答案 0 :(得分:0)

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

代替创建和Array以及从handleSelectWallpaperImageViewhandleSelectWallpaperImageView中选择的两个图像,然后遍历Array并发送到Firebase

请检查此以获取更多信息:https://stackoverflow.com/a/49934285/1244403

答案 1 :(得分:0)

您可以在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)
    }

然后在handleSelectWallpaperImageView方法中轻击wallpaperImageView上,将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

答案 2 :(得分:0)

创建的选项布尔变量

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)



                    }
                }
            })
        }