Reputation: 255
I have looked around for this issue, and have not found an answer that works for my case. Basically, I have a tableView where each cell contains a collectionView. What I would like to do is to refresh the specific TableViewCell where the collectionView was scrolled, in order to update a label under the CollectionView, within that TableViewCell.
So when the user scrolls on the collectionView, I need to know in which cell that collectionView is. I have tried using didSelectRowAtIndexPath, however, it only is called when the non-CollectionView part of the cell is tapped. When the collectionView is tapped or scrolled, it isn't called. I am coding in Swift.
Any ideas on how I can do this?
Thanks!
Upvotes: 0
Views: 768
Reputation: 4425
Your CollectionView will be contained within some kind of cell. Once you have found this cell, you can ask the table for the index. Navigate from your CollectionView up the view hierarchy to find the cell. For example:
CollectionView* collectionView = // your collectionView;
UITableViewCell* cell = (UITableViewCell*)[collectionView superview];
UITableView* table = (UITableView *)[cell superview];
NSIndexPath* pathOfTheCell = [table indexPathForCell:cell];
NSInteger rowOfTheCell = [pathOfTheCell row];
NSLog(@"rowofthecell %d", rowOfTheCell);
Upvotes: 0
Reputation: 1690
This seems like a architecture issue. Sure it can be done the way you want, but it'd be much easier if your rearranged some things. There is a fundamental problem how you want to do this. You want to manage all of the cells and their collection views directly from your view controller. But this poses the problem of needing to know where messages are coming from and directing messages back to the correct cells and collection views. This will create a lot of bloat that can be fixed with a simple UITabelViewCell subclass. It also is a step in contracting Massive View Controller syndrome. Instead, you should make the individual cells responsible for managing their own collection views.
First off, make the UITableViewCell own and be the delegate and data source of the UICollectionView. This centralizes the data and more closely models the tree of data that you actually see on screen.
class CollectionTableViewCell: UITableViewCell {
@IBOutlet var collectionView: UICollectionView! {
didSet(newCollectionView) {
newCollectionView.delegate = self;
newCollectionView.dataSource = self;
}
}
var model: NSArray?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
extension CollectionTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return model?.count ?? 0
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath)
// configure cell
return cell
}
}
Now you wanted to have a state refresh when your collection view scrolls. So we're going to add a label to the cell in the prototype cell (Nib or Storyboard.)
@IBOutlet var indicatorLabel: UILabel!
And you want to update it when the collection view is scrolled. We can do that with the scrollViewDidScroll method off the UIScrollViewDelegate protocol. Because UICollectionViewDelegate implements the UIScrollViewDelegate, it's available for us to use since we implement the UICollectionViewDelegate in our extension.
// in the CollectionTableViewCell extension...
func scrollViewDidScroll(scrollView: UIScrollView) {
let scrollViewOffset = scrollView.contentOffset.x
let scrollViewWidth = CGRectGetWidth(scrollView.frame)
let completionString = String(format: "%@ / %@", scrollViewOffset, scrollViewWidth)
self.indicatorLabel.text = completionString
}
So by making the individual cells responsible for their own respected collection views, we make managing them easier. It allows us organize our code to be more compact, understandable, and keeps us from getting Massive View Controller syndrome. The more code you can move out of your view controller, the better.
Some good talks to hear on this would be:
WWDC 2014 – Advanced iOS Application Architecture and Patterns
Let's Play: Refactor the Mega Controller!
Upvotes: 2
Reputation: 38142
You can use tag
property of UITableViewCell
. Set tag
to row
number and when cell is tapped, fetch tag
property to find out the tapped cell index.
Upvotes: 1