-->

How can I dynamically resize a header view in a UI

2019-04-09 15:49发布

问题:

I have header (a UICollectionReusableCell) in a UICollectionView whose height needs to be variable. How can I have it resize itself according to the height of its contents?

I do not need to support iOS 7, and Autolayout solutions are preferable (if they exist).

回答1:

This is how I solved it. I wish it was more elegant.

  1. Set the UILabel in the header view to have a numberOfLines value of 0. This will let it resize itself.
  2. Move the header out of the storyboard and into a xib.
  3. In collectionView(_:layout:referenceSizeForHeaderInSection:) instantiate a header from the xib. We'll use it to compute a size.
  4. Set the header to the desired width (in my case the width of the collection view), and configure it with the desired text and images
  5. Call setNeedsLayout and layoutIfNeeded.
  6. Use systemLayoutSizeFittingSize(UILayoutFittingCompressedSize) to compute the height.
  7. Return the height and width as CGSize

Notes:

  • The header must be moved out of the storyboard and into a xib because calling dequeuReusableSupplementaryViewOfKind from systemLayoutSizeFittingSize(UILayoutFittingCompressedSize) causes a crash.

  • The header view must be able to compute a correct height only knowing its content and the desired width. This took some fiddling with the constraints.



回答2:

Here would be my approach -

  1. Create outlets for your header and your contents.
  2. Get the height of your contents
  3. Set the height of your header as a % of the contents

In your View Controller -

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let cell = yourCollectionView.dequeueReusableCellWithReuseIdentifier("YourCustomCell", forIndexPath: indexPath) as! YourCustomeCell
    ...
    cell.setUpCell()
    return cell
}

In your View Cell -

@IBOutlet weak var headerView: UIView!
@IBOutlet weak var contentView: UIView!
func setUpCell() {
    let percentageYouWant = 0.3
    let newFrame = CGRect(x: 0, y: 0, width: contentView * percentageYouWant, height: contentView * percentageYouWant)
    headerView.frame = newFrame
}