Selector to Get Indexpath Uicollectionview Swift 3.0

Selector to get indexPath UICollectionView Swift 3.0

First of all you are adding tapGesture to collectionView instead of subOptioncell.

It should be:

subOptioncell.addGestureRecognizer(tap)

Instead of:

collectionView.addGestureRecognizer(tap)

You cannot pass other instance with selector of UIGestureRecognizer, the only instance you can pass is UI(Tap)GestureRecognizer. If you want the indexPath of that cell you can try like this. First of all set your selector of TapGesture like this.

let tap =  UITapGestureRecognizer(target: self, action: #selector(doubleTapped(sender:)))

Now method should be like:

func doubleTapped(sender: UITapGestureRecognizer) {
if let cell = sender.view as? SubOptionsCollectionViewCell, let indexPath = self.collectionView.indexPath(for: cell) {
print(indexPath)
}
}

Edit: If you want to show/hide image on cell double tap then you need to handle it using indexPath of cell, for that first declare one instance of IndexPath and use it inside cellForItemAt indexPath.

var selectedIndexPaths = IndexPath()

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
//Your code
//Now add below code to handle show/hide image
cell.subOptionSelected.isHidden = self.selectedIndexPaths != indexPath
return cell
}

Now on doubleTapped action of UITapGestureRecognizer set the selectedIndexPath.

func doubleTapped(sender: UITapGestureRecognizer) {
if let cell = sender.view as? SubOptionsCollectionViewCell, let indexPath = self.collectionView.indexPath(for: cell) {
if self.selectedIndexPaths == indexPath {
cell.subOptionSelected.isHidden = true
self.selectedIndexPaths = IndexPath()
}
else {
cell.subOptionSelected.isHidden = false
self.selectedIndexPaths = indexPath
}
}
}

Get IndexPath of CollectionViewCell outside of Cell

Get the location of the tapGestureRecognizer in the collectionView and then the indexPath at the given location

let pointInCollectionView = tapGestureRecognizer.location(in: collectionView)
let indexPath = collectionView.indexPathForItem(at: pointInCollectionView)

Swift 5 CollectionView get indexPath by longPress cell

Start by getting the coordinates of the press using gesture.location(in:) Ref: https://developer.apple.com/documentation/uikit/uigesturerecognizer/1624219-location

Then use indexPathForItem(at:) to retrieve the IndexPath of the cell touched. Ref: https://developer.apple.com/documentation/uikit/uicollectionview/1618030-indexpathforitem

Based on this you probably do not need a different gesture recognizer for each cell, you can probably register it with the collection view once.


Solution provided by George Heints based on the above:

@objc func longPress(_ longPressGestureRecognizer: UILongPressGestureRecognizer) {

if longPressGestureRecognizer.state == UIGestureRecognizer.State.began {
let touchPoint = longPressGestureRecognizer.location(in: collectionView)
if let index = collectionView.indexPathForItem(at: touchPoint) {
self.delegateAlbumView?.longPressGetstureDetected(id: albumsDataOrigin[index.row].id ?? 0)
}
}
}

I would recommend to use the State.recognized instead of State.began, your mileage may vary!

How to get cell atIndex in UICollectionView with swift?

This is the way to get the cell at a given indexPath:

let cell = collectionView!.cellForItemAtIndexPath(indexPath)

However, you also might want to try:

cell.contentView.backgroundColor = UIColor.blueColor()

NOTE:

Though the above may have worked, I want to encourage you to try a different implementation to achieve the same functionality. Your implementation would require you to have a separate Action# function for each CollectionViewCell, as well as create the indexPath manually in each of those methods, when you could potentially only have one!

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as! CollectionViewCell
cell.backgroundColor = UIColor.blackColor()
cell.buttonView.addTarget(self, action: Selector("action"), forControlEvents: UIControlEvents.TouchUpInside)
return cell
}

and the function for that one method would be something like:

func action(sender: UIButton!) {
var point : CGPoint = sender.convertPoint(CGPointZero, toView:collectionView)
var indexPath = collectionView!.indexPathForItemAtPoint(point)
let cell = collectionView!.cellForItemAtIndexPath(indexPath)
cell.backgroundColor = UIColor.blueColor()
}

Updated action function for Swift 4.2

@objc func action(sender: Any){
print("tickedOffPressed !")
if let button = sender as? UIButton {
let point: CGPoint = button.convert(.zero, to: collectionView)
if let indexPath = collectionView!.indexPathForItem(at: point) {
let cell = collectionView!.cellForItem(at: indexPath)
cell?.backgroundColor = UIColor.blue
}
}
}

Just a suggestion! Happy coding! :)

Cannot get indexPath and selection on Collection View

Seems like your problem relates to the UITapGestureRecognizer you are adding to your view in configureSuperView(). The touches that would usually trigger the collectionView didSelectItemAt... delegate function are being sent to the gesture recognizer's handler, which is hideKeyboard().

Comment the line with view.addGestureRecognizer(viewTap) and your code will work. If so, I can also help you with achieving the hideKeyboard functionality, just let me know.

How to get CollectionViewCell indexPath on Out-sided UIButton Click

import UIKit

class ViewController: UIViewController ,UICollectionViewDelegate&UICollectionViewDataSource&UICollectionViewDelegateFlowLayout{

@IBOutlet weak var collectionView: UICollectionView!

var currentIndexPath:IndexPath!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
collectionView.delegate = self
collectionView.dataSource = self

}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.backgroundColor = indexPath.row % 2 == 1 ? .blue : .red
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
currentIndexPath = indexPath
}

@IBAction func indexPathAction(_ sender: UIButton) {
print("Current IndexPath",currentIndexPath)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return collectionView.bounds.size
}

}

Selector In Swift 3.0

You can declare selector in Swift 3 like this.

var itemSelected: Selector?

Or

var itemSelected = #selector(tapGesture) 

Later you can use above itemSelected selector with action like this.

For eg:

let tap = UITapGestureRecognizer(target: self, action: itemSelected)

And tapGesture is declared like

func tapGesture(_ sender: UITapGestureRecognizer) { }

Edit: You have added collectionView inside your TableViewCell, so to get the selected IndexPath of CollectionViewCell, declare one protocol and use it with your tableViewCell.

protocol SelectedCellDelegate {
func getIndexPathOfSelectedCell(tableIndexPath: IndexPath, collectionViewCell indexPath: IndexPath)
}

Now create one instance of SelectedCellDelegate and instance of IndexPath within your CustomTableViewCell.

class CustomTableCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource {
//All outlet

var delegate: SelectedCellDelegate?
var tableCellIndexPath = IndexPath()

//CollectionViewDataSource method

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.delegate?.getIndexPathOfSelectedCell(tableIndexPath: tableCellIndexPath, indexPath: indexPath)
}

}

Now inside your ViewController where you have added TableView implement the protocol SelectedCellDelegate and set the delegate and tableCellIndexPath in cellForRowAt indexPath method.

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SelectedCellDelegate {
//your methods

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell // Initialize the cell with your custom TableCell
cell.delegate = self
cell.tableCellIndexPath = indexPath
return cell
}

Now add the delegate method in your ViewController.

func getIndexPathOfSelectedCell(tableIndexPath: IndexPath, collectionViewCell indexPath: IndexPath)  {
print("TableView cell indexPath - \(tableIndexPath)")
print("CollectionView cell indexPath - \(indexPath)")
}


Related Topics



Leave a reply



Submit