UICollectionView 作为 UITableView 子视图流布局循环

Posted

技术标签:

【中文标题】UICollectionView 作为 UITableView 子视图流布局循环【英文标题】:UICollectionView as UITableView subview flow layout loop 【发布时间】:2015-07-06 16:44:11 【问题描述】:

我有一个 UITableView,我想在 tableView 的 backgroundView 中添加一个具有水平流布局的 UICollectionView 作为子视图,以实现与 AppStore 相同的效果。这里我有实现代码:

在viewDidLoad中:

UIView *tableViewBackgroundView = [[UIView alloc] initWithFrame:self.view.bounds];
    self.tableView.backgroundView = tableViewBackgroundView;

// HighlightView heightFactor returns the reason which is  9.0/16.0
    CGFloat headerViewHeight = CGRectGetWidth(self.view.frame) * [HighlightView heightFactor];
    self.tableView.contentInset = UIEdgeInsetsMake(headerViewHeight, 0, 0, 0);
    self.headerView = [[HighlightView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), headerViewHeight)];
    [tableViewBackgroundView addSubview:self.headerView];

HighlightView 是一个内部带有 collectionView 的视图。

但是我遇到了一个问题,当用户与 collectionView 交互时,我开始收到此日志:

请检查委托人返回的值。的行为 UICollectionViewFlowLayout 未定义,因为:项目高度 必须小于 UICollectionView 减去部分的高度 插入顶部和底部值。

这变成了一个循环,即使用户停止交互也不会停止。

HighlightView(CollectionView)代码:

override init(frame: CGRect) 
    super.init(frame: frame)
    self.viewModel.delegate = self
    self.configureHighlightsCollectionView()


func configureHighlightsCollectionView() 

    let flowLayout = UICollectionViewFlowLayout()
    flowLayout.scrollDirection = UICollectionViewScrollDirection.Horizontal
    flowLayout.minimumInteritemSpacing = 0
    flowLayout.minimumLineSpacing = 0
    if systemVersion > 8.0 
        flowLayout.estimatedItemSize = self.frame.size
    
    flowLayout.itemSize = self.frame.size
    self.highlightsCollectionView = UICollectionView(frame: self.bounds, collectionViewLayout: flowLayout)
    self.highlightsCollectionView.frame = self.bounds
    self.highlightsCollectionView.scrollsToTop = false
    self.highlightsCollectionView.pagingEnabled = true
    self.highlightsCollectionView.registerClass(CachedImageCollectionViewCell.self, forCellWithReuseIdentifier: "ImageCell")
    self.addSubview(self.highlightsCollectionView)

    self.highlightsCollectionView.invalidateIntrinsicContentSize()

    self.highlightsCollectionView.dataSource = self
    self.highlightsCollectionView.delegate = self
    self.highlightsCollectionView.backgroundColor = UIColor.greenColor()

    self.highlightsCollectionView.snp_makeConstraints  (make) -> Void in
        make.top.equalTo(self)
        make.bottom.equalTo(self)
        make.left.equalTo(self)
        make.right.equalTo(self)
    


//Mark: UICollectionViewDataSource
    public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return self.viewModel.highlightsArray.count
    

public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("ImageCell", forIndexPath: indexPath) as! CachedImageCollectionViewCell
    cell.highlightData = self.viewModel.highlightsArray[indexPath.item]
    return cell


public func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize 
    println(self.frame.size)
    return self.frame.size

viewModel是一个控制collectionView的数据流向的类。

【问题讨论】:

为什么不直接使用 tableview 的 headerView 属性?如果您使用自动布局,则必须为您的视图设置约束。 因为动画效果,当你使用Header时,它会随着内容滚动,当你用作背景时,内容会在它的上方滚动。是的,我已经设置了约束,即使没有任何类型的自动布局,问题也会发生 当然。无论如何,您的问题来自您的 UICollectionView 及其布局,您应该添加一些关于它的代码 【参考方案1】:

首先,我认为将视图作为数据源和 UICollection 的委托放在 UIView 子类中并不是一个好主意。您不尊重 MVC 模式。在Introducing ios Design Pattern 了解有关它的更多信息。您应该将控制器设置为它。

问题是您在 initFrame: 中根据您的视图框架设置 UICollectionViewFlowLayout 的 itemSize。在该方法中,您的 UIView 的框架不正确,因为您使用的是 AutoLayout。你必须等到 AutoLayout 计算出你的视图的布局,所以当 layoutSubviews: 被调用时。在Matt's book 中了解 UIView 和 AutoLayout。它适用于 iOS 6 和 Objective-C,但仍然很棒。

【讨论】:

嘿,我尝试将代码更改为 layoutSubviews 或 drawRect(),结果相同,循环不断发生。感谢您的帮助,我会研究这些文章。我认为问题在于 TableView/CollectionView 滚动层次结构 您是否将集合视图的 sectionInset 设置为 UIEdgeInsetsZero ? 不,应该吗?这会做什么? developer.apple.com/library/ios/documentation/WindowsViews/… 在“使用部分插图调整内容的边距” 不幸的是,默认的边缘插入都设置为 0。所以这不是问题。

以上是关于UICollectionView 作为 UITableView 子视图流布局循环的主要内容,如果未能解决你的问题,请参考以下文章

numberOfItemsInSection 的逻辑问题:

框架没有正确更新 UICollectionView 作为 UITableViewCell 子视图

UICollectionView 作为 UITableView 子视图流布局循环

UICollectionView 作为子视图不会更新约束

以 UIViewController 作为数据源的 UICollectionView

如何使用 UISearchBar 或 UISearchDisplayController 作为 UICollectionView 标头?