自动调整UICollectionView标题

我正在尝试做一个待办事项列表类应用程序的详细屏幕。 以下是详细信息屏幕当前的样子:

细节屏幕

这是一个带有标题的UICollectionViewController 。 标题包含2个UILabel对象和一个UITextView对象。 这些对象的布局由一个垂直的UIStackView来pipe理。 UIView用于设置白色背景。

我在运行时定义这个UICollectionReusableView的高度有一些困难。 任何意见表示赞赏。

这里是你如何处理自定义UICollectionViewReusableView自动布局没有XIB文件。

  1. 实现referenceSizeForHeaderInSection委托方法。
  2. 在其中,实例化您用作标题视图的视图。
  3. 将其可见性设置为隐藏,以避免闪烁。
  4. 将视图添加到collectionview的超级视图。
  5. 使用自动布局设置它的布局,以匹配标题的预期视觉效果。
  6. 调用setNeedsLayoutlayoutIfNeeded
  7. 从超级视图中移除视图

小心:我不是这个解决scheme的忠实粉丝,因为它每次都将自定义视图添加到collectionview的超级视图中,以执行计算。 虽然我没有注意到任何性能问题。

小心#2:我把它当作一个临时的解决scheme,并且一旦它们出版,就会迁移到自我尺寸的补充视图。

我正在使用PureLayout进行自动布局。

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { let header = CustomHeaderView() header.isHidden = true; self.view.addSubview(header) header.autoPinEdge(toSuperviewEdge: .leading) header.autoPinEdge(toSuperviewEdge: .trailing) header.autoPin(toTopLayoutGuideOf: self, withInset: 0) header.setupHeader(withData: self.data) header.setNeedsLayout() header.layoutIfNeeded() header.removeFromSuperview() return header.frame.size } 

这是一个黑客,但似乎工作。

 // showhere to keep a reference UICollectionReusableView * _cachedHeaderView; - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{ if(!_cachedHeaderView){ // dequeue the cell from storyboard _cachedHeaderView = [collectionView dequeueReusableCellWithReuseIdentifier:[NSString stringWithFormat:@"header_cell"] forIndexPath:indexPath]; // set captions/images on the header etc... // tell the collectionview to redraw this section [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section]]; } return _cachedHeaderView; } - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{ // once there is a reference ot the view, use it to figure out the height if(_cachedHeaderView){ return [_cachedHeaderView systemLayoutSizeFittingSize:collectionView.bounds.size withHorizontalFittingPriority:UILayoutPriorityRequired verticalFittingPriority:UILayoutPriorityDefaultLow]; } // a placeholder value just to get the dequeueReusableCellWithReuseIdentifier to work return CGSizeMake(collectionView.bounds.size.width, 100); }