Add a tap event to CollectionViewCell while passing Cell data - ios

I want to add a tap event to my CollectionViewCell and to pass there my cell with the data it has. How can I achieve this?
Should this event be handled by my ViewController or by CollectionViewCell?
My ViewController:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
cell.imgImage.image = imageArray[indexPath.row]
cell.url = "xhini"
return cell
}
My CollectionViewCell:
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var imgImage: UIImageView!
var url: String = "url"
}

Implement UICollectionViewDelegate and then you can use following method in the ViewController to react to selecting a cell:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let image = imageArray[indexPath.row]
// do stuff with image, or with other data that you need
}
Don't forget to set the delegate where you set a data source:
collectionView.dataSource = self
// add this line:
collectionView.delegate = self
UPDATE
Or if you are using a storyboards, you want to set it using storyboards the same way as you set a dataSource for the dataSource of the tableView:
UPDATE 2
Your tap gesture recognizer cancels event for the collection view, so to deal with this, just uncomment the line tap.cancelsTouchesInView = false, and it will work:
//Looks for single or multiple taps.
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.dismissKeyboard))
//Uncomment the line below if you want the tap not not interfere and cancel other interactions.
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)

I saw your code which you shared in the above answer by #Milan and figured out the reason.
You have added a tap gesture on viewDidLoad of ViewController :
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
This makes the UICollectionView's didSelectItemAt not getting called.
So comment this code and it should work.
For this gesture, you have to find another approach

Related

UITapGestureRecognizer crashing app when clicking on collection view cell

I'm trying to allow user interaction in my collection view. I have decided to try to implement UITapGestureRecognizer to do this. I have tried adding a UITapGestureRecognizer to the collectionview itself and to the collectionview cell. Both ways crash the app. Here is how I am adding the UITapGestureRecognizer to the cell.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionview.dequeueReusableCell(withReuseIdentifier: "userCell", for: indexPath) as! UserCell
cell.userImage.sd_setImage(with: URL(string: self.user[indexPath.row].imagePath))
cell.nameLabel.text = self.user[indexPath.row].username
cell.userID = self.user[indexPath.row].userID
let singleTap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "segueToProfile:")
singleTap.numberOfTapsRequired = 1
singleTap.numberOfTouchesRequired = 1
cell.addGestureRecognizer(singleTap)
return cell
}
When I tap on the cell I get a SIGABRT in the AppDelegate. The error message reads "terminating with uncaught exception of type NSException". What am I doing wrong. UITapGestureRecognizer.
This is my segueToProfile function:
func segueToProfile(gesture: UITapGestureRecognizer) {
// if(recognizer.state == UIGestureRecognizer.State.ended){
// print("myUIImageView has been tapped by the user.")
// }
print("hell world")
}
If you use didSelectItemAt method of collectionView your codebase look readable and maintainable.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
currentViewController.performSegue(withIdentifier: "YourSegueName", sender: nil)
}
First, I would get rid of tapgesturerecognizer as didSelectItem should handle what you are trying to accomplish. That being said, in order for this to work you must:
Remove tapgesturerecognizer
Ensure that the collection view delegate is set to self.
e.g. <yourColletionViewName>.delegate = self
Above can be assigned at viewDidLoad()

CollectionView cell is selected when swiped on

I have a collectionView showing cells. When I drag/touch/slide my finger on an item, if the touch ends on the item, the cell is selected (segues to the details screen).
Is there any way to limit cell selection (didSelectItemAt indexPath) to a simple tap? i.e it shouldn't select the cell if finger is dragged on an item and the touch ends on it.
Is this the default behavior?
I feel like it might be the cause of a cryptic issue with my custom navigation.
Thanks
Do add Following in your cellForItem
let tap = UITapGestureRecognizer(target: self, action: #selector(cellTapped(tapGestureRecognizer:)))
tap.numberOfTapsRequired = 1
cell.addGestureRecognizer(tap)
And add following function
#IBAction func cellTapped(tapGestureRecognizer: UITapGestureRecognizer)
{
//Do your required work.
}
You can use UITapGestureRecognizer, cause it will only respond on Tap gesture:
#objc func tapAction(_ sender: UITapGestureRecognizer) {
// TODO: - Action you need
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: <CellReuseId>, for: indexPath)
let tap = UITapGestureRecognizer(target: self, action: #selector(tapAction(_:)))
cell.contentView.addGestureRecognizer(tap)
return cell
}
But in this way didSelectItemAt will not work.

UITapGestureRecognizer won't work for custom UIView class

I have a custom UIView class which creates a checkbox. This UIView is in a custom table view cell.
I have this code in cellForRowAt
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TransactionsTableViewCell
cell.isUserInteractionEnabled = true
cell.addSubview(cell.test)
let gesture = UITapGestureRecognizer(target: self, action: #selector (self.recurringChange(_:)))
cell.test.isUserInteractionEnabled = true
cell.test.addGestureRecognizer(gesture)
}
I have have this function in the ViewController class
#objc func recurringChange(_ sender:
UITapGestureRecognizer) {
print("test")
}
When test view is tapped, it does not print test. I tried this with a normal UIView (not custom), and it worked exactly as expected.
If this helps, here is a link to the custom class: https://github.com/vladislav-k/VKCheckbox
I have tested the code in Xcode 10 and there is no problem.
You may check " cell.isUserInteractionEnabled = true"
and "cell.addSubview(test)" is added to cell before you add TapGesture.

didSelectItemAt indexPath called after a long press

I have used collectionview and set the imageview in collection view cell. i need to move another viewcontroller after the cell was touched. But my problem is the view moves after a long press on cell in collection view.
This is my code.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
let imagesPath = documentPath.appendingPathComponent(reportImageFolder)
let cell = arrImagesFiltered[indexPath.item]
let imageNameWithPath = "\(imagesPath)/\(cell)"
let imageEditViewController = self.storyboard?.instantiateViewController(withIdentifier: "EditImageViewController") as! EditImageViewController
imageEditViewController.imagePath = imageNameWithPath
self.navigationController?.pushViewController(imageEditViewController, animated: true)
}
For future readers of this old question - probably me in the future ;)
I had a UITapGestureRecognizer which was swallowing my short taps and hence only the old taps were making it through! You just need to add tapRecognizer.cancelsTouchesInView = false!
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapDidTouch(sender:)))
tapRecognizer.cancelsTouchesInView = false
scrollView.addGestureRecognizer(tapRecognizer)

Add Pan Gesture to UICollectionView Cell - IOS/Swift

I have an UICollectionView and I want to add pan gesture to its Cells/Items. When I add the gesture in usual way UICollectionView is not getting scrolled.
This is how I add the gesture
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell:UICollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath)
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(CaptureViewController.pagesCollectionViewItemPanEvent(_:)))
cell.addGestureRecognizer(panGesture)
return cell;
}
Is there something wrong here? Can someone please tell me a way to get my work done. Any help would be highly appreciated.
You should add the gesture to the collection view and not to the cell itself.
Something like...
let panGesture = UIPanGestureRecognizer(target: self, action: "handlePanGesture:")
collectionView.addGestureRecognizer(panGesture)
func handlePanGesture(gesture: UIPanGestureRecognizer) {
let locationInView = gesture.locationInView(collectionView)
...
}
Just a proposal, I didn't test it:
Create a custom cell:
class PanCell: UICollectionViewCell {
override func awakeFromNib() {
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.pagesCollectionViewItemPanEvent(_:)))
self.addGestureRecognizer(panGesture)
}
}
and you can use the delegation to inform CaptureViewController.

Resources