Skip to content

Commit

Permalink
Added Readme and video
Browse files Browse the repository at this point in the history
  • Loading branch information
strawberrycode committed May 29, 2016
1 parent c796c36 commit 3ce6e74
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 21 deletions.
Binary file added Images/SCCollectionViewCustomLayout.m4v
Binary file not shown.
27 changes: 27 additions & 0 deletions README.md
@@ -0,0 +1,27 @@
# UICollectionView Custom Layout: the Ultimate Tutorial

This project shows the basics about how to create a custom `UICollectionViewFlowLayout` for a `UICollectionView`.

To cover most of the configurations you can encounter while working on a `UICollectionView`, I created 3 sections with 3 different layouts:
- section 1: a cell with fixed size
- section 2: a cell with a fixed width and a dynamic length
- sections 3 & 4: multiple cells aligned on a grid, with fixed size

I also added resizable headers in the sections 3 and 4.

![Video of the custom layout](https://github.com/strawberrycode/SCCollectionViewCustomLayout/blob/master/Images/SCCollectionViewCustomLayout.mp4)


## Tutorials

You will find all the details about the project in 2 tutorials:
- [UICollectionView Custom Layout: the Ultimate Tutorial - Part 1](http://bit.ly/1TNFd1m): how to create the `UICollectionView`. It's an easy prerequisite for Part 2.
- [UICollectionView Custom Layout: the Ultimate Tutorial - Part 2](http://bit.ly/20Q1bPZ): how to create the `UICollectionViewFlowLayout`... and how it works!

## Compatibility

This project works on all iPhones and iPad (portrait, landscape, and with multitasking). Give it a try!

## Contact

You can ping me on Twitter [@cath_schwz](https://twitter.com/cath_schwz), open an issue on GitHub or leave a comment on my blog [strawberrycode.com](http://bit.ly/1TNFd1m) :)
8 changes: 4 additions & 4 deletions SCCollectionViewCustomLayout/Base.lproj/Main.storyboard
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
Expand Down Expand Up @@ -60,13 +60,13 @@
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="94n-ma-Hvp">
<rect key="frame" x="0.0" y="0.0" width="284" height="27"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="22"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="r52-OY-0VX">
<rect key="frame" x="0.0" y="35" width="284" height="99"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
Expand Down Expand Up @@ -105,7 +105,7 @@
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Whw-dg-FGn">
<rect key="frame" x="0.0" y="188" width="184" height="55"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
Expand Down
34 changes: 17 additions & 17 deletions SCCollectionViewCustomLayout/MyCollectionViewFlowLayout.swift
Expand Up @@ -17,31 +17,31 @@ class MyCollectionViewFlowLayout: UICollectionViewFlowLayout {
var layoutHeaderInfo = [NSIndexPath: UICollectionViewLayoutAttributes]()
var collectionViewWidth: CGFloat = 0
var maxOriginY: CGFloat = 0

// keep track of max height values to avoid scroll jumps when you have a long collectionView
var headerHeight = [NSIndexPath: CGFloat]()
var textHeight: CGFloat = 0.0

var itemsPerRow = 0

let numberOfSections = 4

let sectionImage = 0
let sectionText = 1
let sectionItem = 2
let sectionItem2 = 3


override init() {
super.init()
setup()
}

required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
setup()
}

func setup() {
// setting up some inherited values

Expand All @@ -57,8 +57,8 @@ class MyCollectionViewFlowLayout: UICollectionViewFlowLayout {
itemWidth = getItemWidth()
headerReferenceSize = CGSizeMake(collectionViewWidth, 50)
}


func getItemWidth() -> CGFloat {
// small iphones: 2 items in a row
// iPhone 6+ 3
Expand Down Expand Up @@ -125,13 +125,13 @@ class MyCollectionViewFlowLayout: UICollectionViewFlowLayout {
}
layoutInfo[indexPath] = itemAttributes

// print("- \(i).\(j): itemAttributes y: \(itemAttributes.frame.origin.y) - itemAttributes height: \(itemAttributes.frame.size.height) - maxOriginY: \(maxOriginY)")
// print("- \(i).\(j): itemAttributes y: \(itemAttributes.frame.origin.y) - itemAttributes height: \(itemAttributes.frame.size.height) - maxOriginY: \(maxOriginY)")
}
}
}
}


func frameForItemAtIndexPath(indexPath: NSIndexPath) -> CGRect {

if (indexPath.section == sectionImage) {
Expand Down Expand Up @@ -212,12 +212,12 @@ class MyCollectionViewFlowLayout: UICollectionViewFlowLayout {

return allAttributes
}

// MARK: Header and cells layout attributes
override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
return layoutHeaderInfo[indexPath]
}

override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
return layoutInfo[indexPath]
}
Expand All @@ -228,8 +228,8 @@ class MyCollectionViewFlowLayout: UICollectionViewFlowLayout {
// if you don't want to re-calculate everything on scroll
return !CGSizeEqualToSize(newBounds.size, self.collectionView!.frame.size)
}


override func shouldInvalidateLayoutForPreferredLayoutAttributes(preferredAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> Bool {

if (originalAttributes.indexPath.section >= sectionText) {
Expand Down

0 comments on commit 3ce6e74

Please sign in to comment.