Skip to content
This repository has been archived by the owner on Jul 23, 2020. It is now read-only.

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

Repository files navigation

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<String, UICollectionViewCell>()

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

About

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

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages