有时候布局会遇到TableView和CollectionView组合布局,比如上部分是轮播,中间部分是列表显示,最下面是瀑布流,滑动Header还需要悬浮功能,简单的tableView或者collectionView已经无法满足需求了,这样我们可以采用UITableView镶嵌UICollectionView来实现这一需求。
最外面一层使用tableView,在tableView的一个cell镶嵌collectionView,其实最大的问题就是要知道collectionView的高度,这里我们使用kvo来监听它的contentSize值从而获取它的高度。
下面是具体做法:
1、设置镶嵌collectionView的cell的高度为自动,我们使用自动布局来撑满整个cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return indexPath.section == 4 ? UITableViewAutomaticDimension : (indexPath.section == 1 ? 140 : 170);
}
2、cell中先设置collectionView的监听
[self.collectionView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
3、增加collectionView进行自动布局,这里的高度随便设置一个,后面我们监听到contentSize会更新这个值
[self.contentView addSubview:self.collectionView];
[_collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.contentView);
make.height.equalTo(600);
}];
4、监听contentSize更新高度
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
context:(void *)context{
if ([keyPath isEqualToString:@"contentSize"])
{
CGFloat height = self.collectionView.contentSize.height;
[self.collectionView mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@(height));
}];
}
}
5、更新数据源刷新collectionView
[self.collectionView reloadData];
[self.collectionView layoutIfNeeded];
到此大功告成!