Reputation: 851
We have a UITableView
, every row as a UICollectionView
that supports an horizontal scroll
, without paging
enabled.
We has the cells registered for reuse,
// Setup for VenueFilterTableViewCell
NSString * cellIdentifier = @"VenueFilterTableViewCell";
VenueFilterTableViewCell *tbCell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (tbCell == nil) {
tbCell = [[VenueFilterTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier];
tbCell.selectionStyle = UITableViewCellSelectionStyleNone;
}
// Method for inflate the UICollectionView in the row
[tbCell setVenues:venues
loading:NO
atLocation:self.definedLocation
forFilter:filter
withDelegate:self];
cell = tbCell;
When I scroll the row horizontally the UICollectionView
at the indexPath.row
0 in the UITableViewCell
, the indexPath.row
3 (initially out of the screen) scroll at the same time. So, if after scroll horizontal, you move scroll down quickly you can see the row 3, and the row 7... and so on, scrolling at the same time.
I have a progress bar in each cell, for providing feedback to the user how far to the end of the horizontal scroll he is, but because of this reuse behaviour, each row involved (0 and 3 and 7) is messing up the progress of the other.
Any suggestions?
UPDATE
I added into the UITableView
the next event for controlling when the cell is out of the screen and force the UICollectionView
inside to stop scrolling. That enhanced a bit the performance, but eventually the issue happen again.
Code in the UITableViewController
for detecting when the row is out of the screen:
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if ([tableView.indexPathsForVisibleRows indexOfObject:indexPath] == NSNotFound) {
// This indeed is an indexPath no longer visible
// Do something to this non-visible cell...
if ([cell isKindOfClass:[VenueFilterTableViewCell class]]) {
VenueFilterTableViewCell *tbCell = (VenueFilterTableViewCell *) cell;
[tbCell stopScrolling];
}
}
}
Code in the UITableViewCell
with the UICollection
View, in the reload content, apart from recovering the contentOffset, we need to re-enable the self.collectionView.scrollEnabled = YES;
- (void) stopScrolling {
self.collectionView.scrollEnabled = NO;
[self.collectionView setContentOffset:self.collectionView.contentOffset animated:NO];
}
Upvotes: 2
Views: 424
Reputation: 16416
My first answer was not helpful. so I have fixed in this one Sorry to put it in swift you can easily convert that in objc
I have implemented willDisplayCell and endDispayCell with following code
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let cell = cell as? ScreenShotsCell else { return }
self.configureCell(for: indexPath, to: cell)
cell.collectionView.setContentOffset(cell.collectionView.contentOffset, animated: true)
cell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0
}
//--------------------------------------------------------------------------------
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let cell = cell as? ScreenShotsCell else { return }
storedOffsets[indexPath.row] = cell.collectionViewOffset
cell.collectionView.setContentOffset(cell.collectionView.contentOffset, animated: true)
}
Main core logic is cell.collectionView.setContentOffset
so it will stop scroll when it is not visible so it will fix the issue of other row's of tableview scrolling because of reuse cell
Hope it is helpful
Upvotes: 1
Reputation: 20710
Seems like a typical issue caused by cell reusing. If you really have a UICollectionView
as a part of a cell, the best way is to create a Dictionary
of stored offsets.
Quick example:
var storedOffsets: [Int: CGFloat] = [:]
in tableView:didEndDisplaying:forRowAt:
store the offsets of a collectionView's contentOffset
.
and
then in tableView:willDisplay:forRowAt:
use these stored offsets to set the contentOffset
of the collectionView
in the cell.
Upvotes: 0