1

I have added UITapGestureRecognizer for collectionview cell image like

code: with this code if i tap on two cell images then both are showing. Here if i tap on second cell image then how to remove first image from foreground

here touchesBegan not calling when i tap on outside of the newImageView(but on collectionview) why? is there any solution for this

o/p screen of the code

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FriendCollectionViewCell.cellId, for: indexPath) as! FriendCollectionViewCell

let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(cellTappedMethod(_:)))
cell.profileImageView?.gestureRecognizers?.removeAll()
cell.profileImageView.isUserInteractionEnabled = true
cell.profileImageView.tag = indexPath.row
cell.profileImageView.addGestureRecognizer(tapGestureRecognizer)


return cell

}

@objc func cellTappedMethod(_ sender: UITapGestureRecognizer){

let imageView = sender.view as! UIImageView
let newImageView = UIImageView(image: imageView.image)
newImageView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width * 0.7, height: 300.0)//UIScreen.main.bounds
UIView.animate(withDuration: 0.2) { [self] in
    
    newImageView.center = CGPoint(x: UIScreen.main.bounds.center.x - 15, y: UIScreen.main.bounds.center.y - 200)
    
    newImageView.backgroundColor = UIColor.clear
    newImageView.contentMode = .scaleAspectFit
    newImageView.isUserInteractionEnabled = true
    let tap = UITapGestureRecognizer(target: self, action: #selector(dismissFullscreenImage))
    newImageView.addGestureRecognizer(tap)
    
    self.view.addSubview(newImageView)
}
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{

let touch = touches.first
print("touch..outside")

var sender = UITapGestureRecognizer()
print(sender.view?.tag)

if ((touch?.view) != nil){
    print("touch..")
    sender.view?.removeFromSuperview()
}
}



@objc func dismissFullscreenImage(sender: UITapGestureRecognizer) {
UIView.animate(withDuration: 0.2) { [self] in
    sender.view?.removeFromSuperview()
}
}

if i tap on cell image then how to remove all image which are in foreground. please guide me

iOS work
  • 33
  • 6

1 Answers1

1

To achieve the desired behavior of removing the previous image from the foreground when tapping on a new cell image, you can keep track of the currently displayed image view and remove it before adding a new one.

var currentImageView: UIImageView?

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FriendCollectionViewCell.cellId, for: indexPath) as! FriendCollectionViewCell
    
    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(cellTappedMethod(_:)))
    cell.profileImageView?.gestureRecognizers?.removeAll()
    cell.profileImageView.isUserInteractionEnabled = true
    cell.profileImageView.tag = indexPath.row
    cell.profileImageView.addGestureRecognizer(tapGestureRecognizer)
    
    return cell
}

@objc func cellTappedMethod(_ sender: UITapGestureRecognizer) {
    let imageView = sender.view as! UIImageView
    
    currentImageView?.removeFromSuperview()
    
    let newImageView = UIImageView(image: imageView.image)
    newImageView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width * 0.7, height: 300.0)
    newImageView.center = CGPoint(x: UIScreen.main.bounds.center.x - 15, y: UIScreen.main.bounds.center.y - 200)
    newImageView.backgroundColor = UIColor.clear
    newImageView.contentMode = .scaleAspectFit
    newImageView.isUserInteractionEnabled = true
    
    let tap = UITapGestureRecognizer(target: self, action: #selector(dismissFullscreenImage))
    newImageView.addGestureRecognizer(tap)
    self.view.addSubview(newImageView)
    currentImageView = newImageView
}

@objc func dismissFullscreenImage(sender: UITapGestureRecognizer) {
    sender.view?.removeFromSuperview()
    currentImageView = nil
}

In this code the currentImageView variable is declared at the class level to keep track of the image view currently displayed on the screen. When a cell image is tapped, the previous image view (if any) is removed from the superview before adding a new one. The currentImageView variable is updated with the new image view, and when dismissing the full-screen image, the reference is cleared to indicate that no image view is currently displayed.

As for the issue with touchesBegan not being called when tapping outside the newImageView, it's because the newImageView is on top of the collection view and intercepts the touch events. One solution is to subclass UICollectionView and override the touchesBegan method in the subclass.

class MyCollectionView: UICollectionView {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
    }
}
Sudeep P H
  • 244
  • 5
  • Thank you, existing image remove issue fixed but instead of `class MyCollectionView: UIViewController` i cant use `class MyCollectionView: UICollectionView` bcz it leads to so many other issues – iOS work Jun 05 '23 at 05:22