Dynamic-Collection-View-Cell-With-Auto-Layout-Demo

by honghaoz

Collection View on iOS with auto layout in UICollectionViewCell to create cells with dynamic heights

201 Stars 33 Forks Last release: Not found MIT License 41 Commits 0 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

Dynamic-Collection-View-Cell-With-Auto-Layout-Demo

Demo for Collection View on iOS with auto layout in UICollectionViewCell to create cells with dynamic heights

Works on iOS7, iOS8 and iOS9.

Updated

Updated to Swift 2.1.1 Demo can now be displayed in all iPhone screen sizes.

For off screen cells, there's a new dynamic collection view which will handle it gracefully. Check it out! ZHDynamicCollectionView

Explanation

Cell is created in xib file, can be also created in code.

Cell is a basic cell with a title label and a content label. Title label has 1 line text and content label has multiple lines text.

Interface builder

There are totally 7 constraints for two labels:

For the title label, there are top, leading, trailing spacing with superView. For the content label, there are bottom, leading, trailing spacing with superView. And there is a fixed vertical spacing between the bottom of the title label with the top of the content label

All of these 7 constraints have 1000 priority

For two labels, set their Content Hugging Priority and Content Compression Resistance Priority same as following pic:

Title label

Content label

In code

UICollectionViewCell

Subclassing this UICollectionViewCell

In

awakeFromNib()
, for iOS7 remember to set
self.contentView.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]

and in

layoutSubviews()

Set

contentLabel.preferredMaxLayoutWidth
to a preferred value, like
contentLabel.preferredMaxLayoutWidth = self.bounds.width - 2 * kLabelHorizontalInsets

You may also need a configure function, make sure in this function, call

self.setNeedsLayout()
and
self.layoutIfNeeded()

View Controller of UICollectionView

In collectionView's view controller, two key delegate methods are

collectionView:layout:sizeForItemAtIndexPath:
and
cellForItemAtIndexPath:

Since

collectionView:layout:sizeForItemAtIndexPath:
is called before
cellForItemAtIndexPath:
, so we need to initialize a cell and let system use auto layout to calculate height for us. To avoid memory leak, we use a dictionary to cache the cells that are off screen (not shown on screen)

The dictionary variable is

var offscreenCells = Dictionary()

In

collectionView:layout:sizeForItemAtIndexPath:
, first create or retrieve a cell
var cell: MyCollectionViewCell? = self.offscreenCells[reuseIdentifier] as? MyCollectionViewCell
if cell == nil {
    cell = NSBundle.mainBundle().loadNibNamed("MyCollectionViewCell", owner: self, options: nil)[0] as? MyCollectionViewCell
    self.offscreenCells[reuseIdentifier] = cell
}

Once a cell is initialized, its size is determined by size in xib file, thus, we need configure texts in cell and layoutSubviews, this will let system recalculate the size of cell

// Config cell and let system determine size
cell!.configCell(titleData[indexPath.item], content: contentData[indexPath.item], titleFont: fontArray[indexPath.item] as String, contentFont: fontArray[indexPath.item] as String)
// Cell's size is determined in nib file, need to set it's width (in this case), and inside, use this cell's width to set label's preferredMaxLayoutWidth, thus, height can be determined, this size will be returned for real cell initialization
cell!.bounds = CGRectMake(0, 0, targetWidth, cell!.bounds.height)
cell!.contentView.bounds = cell!.bounds

// Layout subviews, this will let labels on this cell to set preferredMaxLayoutWidth cell!.setNeedsLayout() cell!.layoutIfNeeded()

Once cell is updated, call

var size = cell!.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
to get the size for this cell.

In

cellForItemAtIndexPath:
, cell also need configured and layout its subviews

Screen shots

The MIT License (MIT)

Copyright (c) 2014 Honghao Zhang

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Bitdeli Badge

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.