Search code examples
iosswiftgenericsnsindexpathindexpath

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


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
    }

Solution

  • 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.