Creating a UICollectionView programmatically
Solution 1
Header file:--
@interface ViewController : UIViewController<UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
{
UICollectionView *_collectionView;
}
Implementation File:--
- (void)viewDidLoad
{
[super viewDidLoad];
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
_collectionView=[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
[_collectionView setDataSource:self];
[_collectionView setDelegate:self];
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellIdentifier"];
[_collectionView setBackgroundColor:[UIColor redColor]];
[self.view addSubview:_collectionView];
// Do any additional setup after loading the view, typically from a nib.
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 15;
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];
cell.backgroundColor=[UIColor greenColor];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(50, 50);
}
Output---
Solution 2
For swift4 user:--
class TwoViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: flowLayout)
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "collectionCell")
collectionView.delegate = self
collectionView.dataSource = self
collectionView.backgroundColor = UIColor.cyan
self.view.addSubview(collectionView)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 20
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
var cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath as IndexPath)
cell.backgroundColor = UIColor.green
return cell
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSize(width: 50, height: 50)
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
}
}
Solution 3
For Swift 2.0
Instead of implementing the methods that are required to draw the CollectionViewCells
:
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
{
return CGSizeMake(50, 50);
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets
{
return UIEdgeInsetsMake(5, 5, 5, 5); //top,left,bottom,right
}
Use UICollectionViewFlowLayout
func createCollectionView() {
let flowLayout = UICollectionViewFlowLayout()
// Now setup the flowLayout required for drawing the cells
let space = 5.0 as CGFloat
// Set view cell size
flowLayout.itemSize = CGSizeMake(50, 50)
// Set left and right margins
flowLayout.minimumInteritemSpacing = space
// Set top and bottom margins
flowLayout.minimumLineSpacing = space
// Finally create the CollectionView
let collectionView = UICollectionView(frame: CGRectMake(10, 10, 300, 400), collectionViewLayout: flowLayout)
// Then setup delegates, background color etc.
collectionView?.dataSource = self
collectionView?.delegate = self
collectionView?.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellID")
collectionView?.backgroundColor = UIColor.whiteColor()
self.view.addSubview(collectionView!)
}
Then implement the UICollectionViewDataSource
methods as required:
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 20;
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell:UICollectionViewCell=collectionView.dequeueReusableCellWithReuseIdentifier("collectionCell", forIndexPath: indexPath) as UICollectionViewCell;
cell.backgroundColor = UIColor.greenColor();
return cell;
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
Solution 4
Swift 3
class TwoViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let flowLayout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: flowLayout)
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "collectionCell")
collectionView.delegate = self
collectionView.dataSource = self
collectionView.backgroundColor = UIColor.cyan
self.view.addSubview(collectionView)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return 20
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath as IndexPath)
cell.backgroundColor = UIColor.green
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
return CGSize(width: 50, height: 50)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
{
return UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
}
}
Solution 5
You can handle custom cell in uicollection view see below code.
- (void)viewDidLoad
{
UINib *nib2 = [UINib nibWithNibName:@"YourCustomCell" bundle:nil];
[CollectionVW registerNib:nib2 forCellWithReuseIdentifier:@"YourCustomCell"];
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(200, 230)];
flowLayout.minimumInteritemSpacing = 0;
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
[CollectionVW setCollectionViewLayout:flowLayout];
[CollectionVW reloadData];
}
#pragma mark - COLLECTIONVIEW
#pragma mark Collection View CODE
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return Array.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"YourCustomCell";
YourCustomCell *cell = (YourCustomCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
cell.MainIMG.image=[UIImage imageNamed:[Array objectAtIndex:indexPath.row]];
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
}
#pragma mark Collection view layout things
// Layout: Set cell size
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGSize mElementSize;
mElementSize=CGSizeMake(kScreenWidth/3.4, 150);
return mElementSize;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 5.0;
}
// Layout: Set Edges
- (UIEdgeInsets)collectionView: (UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
if (isIphone5 || isiPhone4)
{
return UIEdgeInsetsMake(15,15,5,15); // top, left, bottom, right
}
else if (isIphone6)
{
return UIEdgeInsetsMake(15,15,5,15); // top, left, bottom, right
}
else if (isIphone6P)
{
return UIEdgeInsetsMake(15,15,5,15); // top, left, bottom, right
}
return UIEdgeInsetsMake(15,15,5,15); // top, left, bottom, right
}
Related videos on Youtube
Jimmery
Self taught web developer, who has been crafting websites since 97. Started out programming in Pascal, Visual Basic, C, Java and now enjoys playing about with jQuery/ECMAScript and PHP. Has dabbled with a variety of languages and frameworks, including C#, Swift, Objective C, Actionscript, Node.js, Laravel, Magento and a lot more. And I really love Fab ice lollys (hence the profile pic, obvs...)
Updated on July 08, 2022Comments
-
Jimmery almost 2 years
I'm looking for a guide or tutorial that will show me how to set up a simple UICollectionView using only code.
I'm wading through the documentation on Apples site, and I'm using the reference manual as well.
But I would really benefit from a simple guide that can show me how to set up a UICollectionView without having to use Storyboards or XIB/NIB files - but unfortunately when I search about, all I can find is tutorials that feature the Storyboard.
-
A-Live almost 11 yearsAt the documentation there's a single initializer which you should use instead of any superclass initializer, where do you have problems exactly ?
-
Jimmery almost 11 yearsReally? Ive got as far as the section "Configuring Cells and Supplimentary Views" - have I been a dumb ass and missed this line? Or have I yet to reach it?
-
A-Live almost 11 yearsThe first task is
Initializing a Collection View
, are you using initializer from there ? -
Jimmery almost 11 yearsYes, but this in itself is not enough. I will also need to set up a datasource as well or the App crashes.
-
ArgaPK over 6 years@Jimmery Now how to add image in the cell in this collectionview?
-
-
zontragon about 10 yearsYou should add the collection view as property in IOS7
@property (strong, nonatomic) UICollectionView *collectionView;
-
Pétur Ingi Egilsson about 10 yearsThe setup should happen in -(void)loadView, not in viewDidLoad. As for why it works, the controller first loads default views in its super. Its better to overload loadview and assign your custom views directly.
-
Rob about 10 yearsAlso, if you're programmatically adding any subviews to the
UICollectionViewCell
, you really don't want to be registeringUICollectionViewCell
, but rather you want to subclass it, do your configuration of the cell in theinitWithFrame
method, and then register this subclass with the cell identifier, notUICollectionViewCell
. -
shrishaster about 10 yearsHas anyone else had an error with the above code? It's giving me EXC_BAD_ACCESS error on the line
_collectionView=[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
-
shrishaster about 10 years'self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];' this was missing.
-
JakubKnejzlik almost 10 yearsit should be placed in -loadView, not in -viewDidLoad
-
artud2000 almost 10 yearsYou should never add any code before the call of the super class method in this case [super viewDidLoad]; that's a bad practice read apple documentation
-
hzxu over 9 yearsBut I've read in the apple doc that
The layout object to use for organizing items. The collection view stores a strong reference to the specified object. Must not be nil.
-
Rambatino over 9 yearswhy are we adding this line in? self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
-
Prince Kumar Sharma over 9 yearshi @Rambatino just set frame to main screen bounds , no need to alloc until it is not attached with outlet.
-
Prince Kumar Sharma over 9 yearshi @artud2000, at your suggestion I am editing my answer to get super call first executed. Thanks for suggestion.
-
Stephen Rauch about 7 yearsHow does this differ from the 6 others answers already here? When giving an answer it is preferable to give some explanation as to WHY your answer is the one.
-
ArgaPK over 6 years@Warewolf could you please tell me, How to change the direction of collection view to horizontal??
-
ArgaPK over 6 yearsNow how to add image in this programmatically collectionView ?
-
shvets over 6 years@ArgaPK sure, just add flowLayout.scrollDirection = .horizontal after you instantiate the flowLayout :)
-
Prince Kumar Sharma over 6 years@ArgaPK adding subview to cell in cellForItem method
-
andrewz almost 6 yearsHow are you binding this view controller as a delegate to the collection view layout?