Custom collection view layout with different image and text sizes.
| PinterestVC | Custom Cell |
|---|---|
![]() | ![]() |
- iOS 8.0+
- Swift 3.0+
CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:
$ gem install cocoapodsCocoaPods 1.1.0+ is required to build Reusable 1.0.0+.
To integrate Reusable into your Xcode project using CocoaPods, specify it in your Podfile:
source'https://github.com/CocoaPods/Specs.git'platform:ios,'8.0'use_frameworks!target'<Your Target Name>'dopod'PinterestLayout'endThen, run the following command:
$ pod install- All you need to do is to sublcass from PinterestVC and provide items to be shown.
- PinterestVC will calculate image and text sizes.
import UIKit
import PinterestLayout
classMyPinterestVC:PinterestVC{overridepublicfunc viewDidLoad(){
super.viewDidLoad()lettext="Some text. Some text. Some text. Some text."
items =[PinterestItem(image:UIImage(named:"new_york"), text: text),PinterestItem(image:UIImage(named:"bigben_river"), text: text),PinterestItem(image:UIImage(named:"dubai"), text: text),PinterestItem(image:UIImage(named:"4"), text: text),PinterestItem(image:UIImage(named:"tiger"), text: text)]}}0 - Import PinterestLayout
import PinterestLayout1 - Set PinterestLayout to your collection view.
letlayout=PinterestLayout()
collectionView.collectionViewLayout = layout2 - Setup layout
layout.delegate =self
layout.cellPadding =5
layout.numberOfColumns =23 - Implement methods of PinterestLayoutDelegate
/**
Height for image view in cell.
@param collectionView - collectionView
@param indexPath - index path for cell
Returns height of image view.
*/
func collectionView(collectionView:UICollectionView,
heightForImageAtIndexPath indexPath:IndexPath,
withWidth:CGFloat)-> CGFloat
/**
Height for annotation view (label) in cell.
@param collectionView - collectionView
@param indexPath - index path for cell
Returns height of annotation view.
*/
func collectionView(collectionView:UICollectionView,
heightForAnnotationAtIndexPath indexPath:IndexPath,
withWidth:CGFloat)->CGFloat- PinterestLayout provides public API to easily calculate the best imageview and text heigths based on available width.
publicextensionUIImage{
/**
Calculates the best height of the image for available width.
*/
publicfunc height(forWidth width:CGFloat)->CGFloat
//...
public extension String {
/**
Calculates the best height of the text for available width and font used.
*/
public func heightForWidth(width:CGFloat, font:UIFont)->CGFloat- So implementation of PinterestLayoutDelegate might be:
extensionCustomCollectionVC:PinterestLayoutDelegate{func collectionView(collectionView:UICollectionView,
heightForImageAtIndexPath indexPath:IndexPath,
withWidth:CGFloat)->CGFloat{letimage=images[indexPath.item]return image.height(forWidth: withWidth)}func collectionView(collectionView:UICollectionView,
heightForAnnotationAtIndexPath indexPath:IndexPath,
withWidth:CGFloat)->CGFloat{lettextFont=UIFont(name:"Arial-ItalicMT", size:11)! return"Some text".heightForWidth(width: withWidth, font: textFont)}}4 - Create custom cell and apply PinterestLayoutAttributes
- Example is here
classCollectionViewCell:UICollectionViewCell{
//...
overridefunc apply(_ layoutAttributes:UICollectionViewLayoutAttributes){
super.apply(layoutAttributes)iflet attributes = layoutAttributes as?PinterestLayoutAttributes{
//change image view height by changing its constraint
imageViewHeightLayoutConstraint.constant = attributes.imageHeight
}}}PinterestLayout fully supports collection view headers and footers. So you can have many sections.
In case you load data asynchronously please follow next steps:
- Do not use PinterestVC as parent class to your view controller. Use custom cell approach.
- Make sure server returns image sorce with its sizes (height and width)
{
"src": "/upload/resize_cache/iblock/8e7/204_265_2/8e7f1f04d5e835f596ef33da74946847.jpg",
"width": 204,
"height": 265
}- when data is loaded invalidate layout as well as reload data on collection view.
collectionView.collectionViewLayout.invalidateLayout()
collectionView.reloadData()Contact our team on email - roman.sorochak@gmail.com
PinterestLayout is released under the MIT license. See LICENSE for details.

