Create generic function to get indexpath from table and collection view - iOS - Swift

334 Views Asked by At

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
    }
1

There are 1 best solutions below

1
On BEST ANSWER

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.