Skip to content

Instantly share code, notes, and snippets.

@lamprosg
Last active December 14, 2015 15:18
Show Gist options
  • Select an option

  • Save lamprosg/5106451 to your computer and use it in GitHub Desktop.

Select an option

Save lamprosg/5106451 to your computer and use it in GitHub Desktop.
(iOS) Collection View
Basics:
Cells: cells are the content you wish to display, and inherits their format (bookshelf, circle, line, etc) from a layout that you specify
Supplementary Views: supplementary views are views like labels and section headers/footers
Decoration Views: decoration views are just that – decorations like a bookshelf graphic or a background
---------
Since UICollectionView uses the QuartzCore framework, you need to add that into the project.
---------
Your View class must be subclassed to "UICollectionViewController"
and conform to the "UICollectionViewDelegate"
#import "AppDelegate.h"
//Import viewcontroller and view layout
#import "CollectionViewLayout.h"
#import "ViewController.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//Initialize Collection View Layout
CollectionViewLayout *collectionViewLayout = [[CollectionViewLayout alloc] init];
//Initialize ViewController with the view layout we made and add it as root controller
self.viewController = [[ViewController alloc] initWithCollectionViewLayout:collectionViewLayout];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
@end
//The cell of our collection view needs to be subclassed to "UICollectionViewCell"
@interface Cell : UICollectionViewCell
//This will display something in the cell
@property (retain, nonatomic) UILabel* label;
@end
#import Cell.h
@implementation Cell
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//Initialize the label inside the cell
//Basically we create a custom cell that displays a centered label
self.label = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, frame.size.width, frame.size.height)];
self.label.textAlignment = NSTextAlignmentCenter;
self.label.textColor = [UIColor blackColor];
self.label.font = [UIFont boldSystemFontOfSize:35.0];
self.label.backgroundColor = [UIColor whiteColor];
//Add it to the view
[self.contentView addSubview:self.label];
}
return self;
}
@end
//The meat of creating a nice looking collection view is in the layout itself.
/*A UICollectionViewFlowLayout is a simple layout that allows the views to “Flow”, whether horizontally or vertically.
It organizes items in a grid, flowing the items from each row or column to the next, as many as will fit in each.
Cells do not need to be the same size to utilize UICollectionViewFlowLayout.*/
//The layout you wish to display on the cell needs to be subclassed to "UICollectionViewFlowLayout"
@interface CollectionViewLayout : UICollectionViewFlowLayout
@end
#import "CollectionViewLayout.h"
@implementation CollectionViewLayout
-(id)init {
self = [super init];
if (self) {
//Customize the look and feel of the layout
self.itemSize = CGSizeMake(250, 250);
self.scrollDirection = UICollectionViewScrollDirectionVertical; //or UICollectionViewScrollDirectionHorizontal
self.sectionInset = UIEdgeInsetsMake(100, 0.0, 100, 0.0);
self.minimumLineSpacing = 50.0;
}
return self;
}
//This implementation instructs the layout to reload itself if the bounds change (such as an item getting bigger or smaller.
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)oldBounds {
return YES;
}
//Setup an array of the visual objects, which contains their attributes
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray* array = [super layoutAttributesForElementsInRect:rect];
CGRect visibleRect;
visibleRect.origin = self.collectionView.contentOffset;
visibleRect.size = self.collectionView.bounds.size;
return array;
}
//Tell the view at what point to stop scrolling
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
CGFloat offsetAdjustment = MAXFLOAT;
CGFloat horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView.bounds) / 2.0);
CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
NSArray* array = [super layoutAttributesForElementsInRect:targetRect];
for (UICollectionViewLayoutAttributes* layoutAttributes in array)
{
CGFloat itemHorizontalCenter = layoutAttributes.center.x;
if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offsetAdjustment))
{
offsetAdjustment = itemHorizontalCenter - horizontalCenter;
}
}
return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}
#pragma mark - UICollectionViewFlowLayout Delegate
//Determine the size of the cell
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
// irrelevant example
//..
CGSize retval = photo.thumbnail.size.width > 0 ? photo.thumbnail.size : CGSizeMake(100, 100);
retval.height += 35; retval.width += 35; return retval;
}
//Spacing between the cells, headers, and footers.
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(50, 20, 50, 20);
}
@end
//Your View class must be subclassed to "UICollectionViewController"
//and conform to the "UICollectionViewDelegate"
@interface ViewController : UICollectionViewController <UICollectionViewDelegate>
@end
#import "ViewController.h"
//Import cell and viewlayout
#import "Cell.h"
#import "CollectionViewLayout.h"
@implementation ViewController
//When the view loads
- (void)viewDidLoad
{
[super viewDidLoad];
//Cell will be our custom cell class
[self.collectionView registerClass:[Cell class] forCellWithReuseIdentifier:@"MY_CELL"];
}
//When the view unloads
- (void)viewDidUnload
{
// Release any retained subviews of the main view.
// Release memory if we don't need it
self.colorNames = nil;
}
#pragma mark - Collection View data source
//How many sections are there in the view
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 4;
}
//How many items in each section
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {
return 4;
}
//Drawing cells
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath; {
Cell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"MY_CELL" forIndexPath:indexPath];
cell.label.text = [NSString stringWithFormat:@"%d",indexPath.item];
return cell;
}
#pragma mark - UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
// TODO: Select Item
}
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
// TODO: Deselect item
}
@lamprosg
Copy link
Copy Markdown
Author

lamprosg commented Mar 7, 2013

[self invalidateLayout] reloads the layout, similar to reloadData in the UITAbleView

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment