UITableViewCell内嵌UICollectionView的IndexPath设置问题求助
解决UITableViewCell嵌套UICollectionView的IndexPath判断问题
我之前也碰到过类似的嵌套列表点击索引判断的问题,给你几个实用的落地方案:
方案一:给UICollectionView关联父TableViewCell的索引
这个方案不依赖视图层级,稳定性更高:
- 在你的
FifaPlanTableViewCell类里,添加一个方法用来传递TableView的索引:
- (void)setCollectionViewDataSourceDelegate:(id<UICollectionViewDataSource, UICollectionViewDelegate>)delegate withTableIndexPath:(NSIndexPath *)tableIndexPath { self.collectionView.dataSource = delegate; self.collectionView.delegate = delegate; // 用关联对象把TableView的索引绑定到CollectionView上 objc_setAssociatedObject(self.collectionView, @selector(boundTableIndexPath), tableIndexPath, OBJC_ASSOCIATION_RETAIN_NONATOMIC); [self.collectionView reloadData]; }
- 在TableView的
willDisplayCell方法里,传递当前行的索引:
- (void)tableView:(UITableView *)tableView willDisplayCell:(FifaPlanTableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { [cell setCollectionViewDataSourceDelegate:self withTableIndexPath:indexPath]; }
- 在CollectionView的点击代理方法里,直接取出绑定的索引:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)collectionIndexPath { NSIndexPath *tableIndexPath = objc_getAssociatedObject(collectionView, @selector(boundTableIndexPath)); // 现在你同时拥有两个关键索引: // tableIndexPath = 所在的TableView行 // collectionIndexPath = CollectionView的条目(包含section和item) NSLog(@"点击了TableView第%ld行,CollectionView第%ld组的第%ld个条目", (long)tableIndexPath.row, (long)collectionIndexPath.section, (long)collectionIndexPath.item); }
- 别忘了在Cell复用的时候清理关联对象,避免索引混乱:
// 在FifaPlanTableViewCell的.m文件中 - (void)prepareForReuse { [super prepareForReuse]; objc_setAssociatedObject(self.collectionView, @selector(boundTableIndexPath), nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); [self.collectionView reloadData]; }
方案二:通过视图层级找父TableViewCell
如果不想用关联对象,也可以通过递归查找父视图的方式定位到TableViewCell:
- 先写一个递归查找的工具方法:
- (FifaPlanTableViewCell *)findParentTableViewCellFromView:(UIView *)currentView { if ([currentView isKindOfClass:[FifaPlanTableViewCell class]]) { return (FifaPlanTableViewCell *)currentView; } else if (currentView.superview) { return [self findParentTableViewCellFromView:currentView.superview]; } return nil; }
- 在CollectionView点击方法里调用:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)collectionIndexPath { FifaPlanTableViewCell *parentCell = [self findParentTableViewCellFromView:collectionView]; NSIndexPath *tableIndexPath = [self.tableView indexPathForCell:parentCell]; // 后续逻辑和方案一一致 }
这个方法需要注意视图层级的稳定性,如果后续Cell的内部布局有调整,可能需要修改查找逻辑。
额外提醒
因为你的CollectionView有2个section,处理点击逻辑时一定要注意collectionIndexPath.section的区分,比如不同section的条目跳转逻辑可能不一样,别搞混了。
内容的提问来源于stack exchange,提问作者Syed Faraz Haider Zaidi
相关产品推荐
相关产品推荐

