0

My galleryCollectionView is currently being populated with images from Firebase Database.

I'm having trouble figuring out how to allow the user to long press on an image, and save the selected photo to Photo Library. Right now I am currently stuck on getting the long press to work.

Here is my ViewController (I'm using Swift 4):

class PhotoGalleryViewController: UIViewController, UICollectionViewDataSource, UIGestureRecognizerDelegate {

    @IBOutlet weak var galleryCollectionView: UICollectionView!

    var images = [GalleryImages]()
    var customImageFlowLayout: CustomGalleryCollectionFlowLayout!
    var dbRef: DatabaseReference!

    override func viewDidLoad() {
        super.viewDidLoad()
        let photoLngPrs = UILongPressGestureRecognizer(target: self, action: "handleLongPress")
        photoLngPrs.minimumPressDuration = 0.5
        photoLngPrs.delegate = self
        photoLngPrs.delaysTouchesBegan = true
        self.galleryCollectionView.addGestureRecognizer(photoLngPrs)
        dbRef = Database.database().reference().child("photoGallery")
        customImageFlowLayout = CustomGalleryCollectionFlowLayout()
        galleryCollectionView.collectionViewLayout = customImageFlowLayout
        galleryCollectionView.backgroundColor = UIColor.black
        loadGalleryDB()
        // Do any additional setup after loading the view.
    }

    func loadGalleryDB() {
        dbRef.observe(DataEventType.value, with: {(snapshot) in
            var newGalleryImages = [GalleryImages]()
            for galleryImagesSnapshot in snapshot.children {
                let galleryImagesObject = GalleryImages(snapshot: galleryImagesSnapshot as! DataSnapshot )
                newGalleryImages.append(galleryImagesObject)
            }



            self.images = newGalleryImages
            self.galleryCollectionView.reloadData()
        })
    }

    func handleLongPress(gestureRecognizer : UILongPressGestureRecognizer) {
        if gestureRecognizer.state == UIGestureRecognizerState.began {
            return
        }
        let point = gestureRecognizer.location(in: self.galleryCollectionView)
        let indexPath = galleryCollectionView.indexPathForItem(at: point)
        if let index = indexPath {
            var collectionCell = galleryCollectionView.cellForItem(at: index)
            print(index.row)
        } else {
            print("Could not find Index Path")
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return images.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "galleryCell", for: indexPath) as! GalleryCollectionViewCell
        let image = images[indexPath.row]
        cell.galleryView.sd_setImage(with: URL(string: image.url), placeholderImage: UIImage(named: "NightCLubPhoto"))

        cell.galleryView.isUserInteractionEnabled = true

        return cell
}

Im getting this error.

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Hookaholics.PhotoGalleryViewController handleLongPress]: unrecognized selector sent to instance 0x7fa61bc0d7a0'
Anton Belousov
  • 1,140
  • 15
  • 34
Adrian Navarro
  • 135
  • 2
  • 10
  • 1
    Can you give more details? What is your problem exactly? What is not working and what have you tried. To detect a long press you should check out apple's UILongPressGestureRecognizer (https://developer.apple.com/documentation/uikit/uilongpressgesturerecognizer?changes=_9). And here is a nice explanation how saving works: https://stackoverflow.com/a/40858152/1195661 – palme May 19 '18 at 19:45
  • I would suggest `UILongPressGestureRecognizer` implementation. – Elena May 19 '18 at 19:46

1 Answers1

0

Here's my solution for the cases similar to yours.

You create a UILongPressGestureRecognizer and add it to your CollectionView.

func createLongPressGesture(){

    let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPressOccured(sender:)))
    longPress.minimumPressDuration = 0.7 // Default `minimumPressDuration` is 0.5. It sets the time after which UILongPressGestureRecognizer enters the 'began' state.
    longPress.isEnabled = true
    self.galleryCollectionView.addGestureRecognizer(longPress)

}

You can cal this function inside viewDidLoad.

Next step is to implement the selector:

@objc func longPressOccured(sender:UILongPressGestureRecognizer){

    guard sender.state == .began else{ return }
    guard let pressedIndexPath = self.galleryCollectionView.indexPathForItem(at: sender.location(in: self.galleryCollectionView)) else { return }
    guard let pressedCell = self.galleryCollectionView.cellForItem(at: pressedIndexPath) else { return }
    let cell = pressedCell as! GalleryCollectionViewCell

    // HERE comes your code for saving the selected image

}

Hope I got you problem right and my solution is helpful.

Elena
  • 829
  • 8
  • 20
  • Don't believe there is a indexPathForRow for UICollectionView. – Adrian Navarro May 19 '18 at 21:49
  • Thank you for this though, App isn't crashing now, but still not working. replaced indexPathForRow to indexPathForItem and CellForRow to cellForItem to clear errors. Still not workin – Adrian Navarro May 19 '18 at 21:51
  • @AdrianNavarro I guess I copied from UITableView case, I'll fix this. Could you tell me what is not working exactly? 'Cause I tested this before posting. – Elena May 19 '18 at 22:23
  • excuse me, it does work:) thank you so much. No i just have to figure out how to save the photo to the gallery!:) – Adrian Navarro May 19 '18 at 23:40
  • @AdrianNavarro Thank you for accepting my answer )) Regarding saving the photo to the camera roll there's a function in UIKit that does the job. Consult [documentation](https://developer.apple.com/documentation/uikit/1619125-uiimagewritetosavedphotosalbum). – Elena May 20 '18 at 08:06