Need help with Dynamic-Collection-View-Cell-With-Auto-Layout-Demo?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

honghaoz
199 Stars 33 Forks MIT License 41 Commits 0 Opened issues

Description

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

Services available

!
?

Need anything else?

Contributors list

# 35,689
CSS
Swift
swift-f...
iOS
19 commits
# 424,810
Swift
Objecti...
9 commits
# 570,252
C
C++
Shell
2 commits
# 9,874
autohot...
ahk
bitwise...
Nette
1 commit
# 156,318
HTML
CSS
excel
data-gr...
1 commit
# 7,228
isomorp...
css3
webplat...
executa...
1 commit

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.