0

I have a tableView and collectionView and to get indexPath i'm using below methods on tableViewCell and collectionViewCell (i dont want to use indexPathForSelectedRow/Item methods). Is there a way that I can make this generic?

Ideas please

// For Tableview 
    func getIndexPath() -> IndexPath? {
        guard let superView = self.superview as? UITableView else {
            return nil
        }
        let indexPath = superView.indexPath(for: self)
        return indexPath
    }

// For CollectionView
     func getIndexPath() -> IndexPath? {
        guard let superView = self.superview as? UICollectionView else {
            return nil
        }
        let indexPath = superView.indexPath(for: self)
        return indexPath
    }
Ashh
  • 569
  • 1
  • 6
  • 28
  • I assume these methods are in `UITableViewCell` and `UICollectionViewCell` extensions? – Sweeper Sep 20 '20 at 07:49
  • 4
    IMO if a cell needs to know its index path you are doing something wrong. – Paulw11 Sep 20 '20 at 09:11
  • @Paulw11 Now that I think about it, this is indeed weird. I was just treating this as another "removing duplicate code" exercise, and didn't think too deeply about it. – Sweeper Sep 20 '20 at 10:14
  • I have collectionView within tableCell and there are few buttons in each collection cell..i need to know indexPath of button tapped (from collectionCell) to my viewController...since i have multiple buttons i needed to find indexPath – Ashh Sep 21 '20 at 17:07

1 Answers1

0

You could do this with two protocols, one that both UITableView and UICollectionView conforms to, and the other that both UITableViewCell and UICollectionViewCell conforms to.

protocol IndexPathQueryable: UIView {
    associatedtype CellType
    func indexPath(for cell: CellType) -> IndexPath?
}

protocol IndexPathGettable: UIView {
    associatedtype ParentViewType: IndexPathQueryable
}

extension UITableView : IndexPathQueryable { }
extension UICollectionView : IndexPathQueryable { }

extension UICollectionViewCell : IndexPathGettable {
    typealias ParentViewType = UICollectionView
}
extension UITableViewCell : IndexPathGettable {
    typealias ParentViewType = UITableView
}

extension IndexPathGettable where ParentViewType.CellType == Self {
    func getIndexPath() -> IndexPath? {
        guard let superView = self.superview as? ParentViewType else {
            return nil
        }
        let indexPath = superView.indexPath(for: self)
        return indexPath
    }
}

Really though, you shouldn't need a getIndexPath method on a table view cell. Cells should not know their index paths. I suggest you reconsider your design.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Thanks..I have collectionView within tableCell and there are few buttons in each collection cell..i need to know indexPath of button tapped (from collectionCell) to my viewController...since i have multiple buttons i needed to find indexPath – Ashh Sep 21 '20 at 17:08