Showing posts with label CollectionView in iOS. Show all posts
Showing posts with label CollectionView in iOS. Show all posts

Wednesday, March 6, 2013

UICollection View in iOS 6 Tutorial


Today we are going to learn of the new feature added by Apple guys in iOS 6.



So stay with me, and do it step by step by .. don't forget to drop me a message or comment.

Note : This Application Developed Using : iOS 6

PHASE - I (Create New Project)

So, Let's Fire Xcode!!

Go to File --> New --> Project

Now we can see a Window for selecting our application templet 

So make sure you select Application in iOS option on your Left hand side.
then select Single View Application as shown in below picture and Go for Next..



In the Next Window we need to put Our Project Details this way

Product Name : CollectionViewDemo
Organization Name :RDCWorld
Company Identifier : com.rdcworld

Class Prefix :  (leave it blank for now)

Devices : iPhone

Note : Don't forget to Make Tick mark on "Use Automatic Reference Counting" option.



Go to Next --> Create.

Now you can see Xcode default dashboard with our newly created project .


PHASE - II (Design UI)

We need to add  UICollectionView and UICollectionViewCell on our screen to get it work.

UICollectionView : for showing our data (image, text etc) in a grid form
UICollectionViewCell : for design particular cell on Collection view


So, Just open ViewController.xib file you can see default blank layout
1. let's drag UICollectionView from Object library and fill it on layout as shown in picture




2. now we need to create a Layout for our CollectionView cell, so we are going to add one XIB file.

File Menu --> New --> File

Select View templet in "User Interface" option under iOS (see popup window screen shot), go next



select device family : we are creating for iPhone.



Given it name as "MyCell" and go for create.



Good!! now you can see default blank layout, just delete it (select it and press delete button) and drag UICollectionViewCell from object library



now go the Size Inspector and change width=100 and hight =100



now select Attribute Inspector and change Background color and then drag UILabel on it as below image



select UILabel --> in Attribute Inspector --> scroll down and change its Tag = 100 (because we need to get it in ViewController.m file)

this time our project structure is look like 



PHASE - III (Create IBOutlets and IBAction )

We are going to create IBOutlet for UICollectionView .
So just open ViewController.xib

Okay, Now select Assistant Editor on Top Right side



You can see our ViewController.xib (Left side) + ViewController.h (Right side) opened together.

Select UICollectionView --> Right Click on it 

Click on "New Referencing outlet" option and drag cursor to ViewController.h(right side) file, when your cursor is between @interface and @end you can see like this.



Now you will get Popup Window 

just put Name : "myCollectionView" and click on Connect.



Done!! now back to Standard Editor



PHASE - III (Hook Up Delegate and Datasource)

We need to mentioned that we are going to implement UICollectionView's Datasource and Delegate protocols,
so do it now, later we will define in our ViewController.h file too.

1. sélect ViewController.xib file.
2. select UICollection

On top right corner (below to Organizer tab) select Connection Inspector

Click on DataSource and drag it to the File owner as shown in below screen shot



Now do the same for Delegate (Drag delegate to the file owner)

Note : you can achieve same by adding below two lines in viewDidLoad method of your ViewController.m file 

myCollectionView.dataSource = self;
myCollectionView.delegate=self;

Great!! You are on the way!!

PHASE - IV (Writing Code)

Now Save app, and open ViewController.h file 

1. add UICollectionView's protocols <UICollectionViewDataSource, UICollectionViewDelegate> to @interface 

@interface ViewController : UIViewController<UICollectionViewDataSource, UICollectionViewDelegate>

2. define mutable array with property, name as "contentArray"

@property (nonatomic, retain) NSMutableArray *contentArray;

So Finally our ViewController.h file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  ViewController.h
//  CollectionViewDemo
//
//  Created by RDC on 3/6/13.
//  Copyright (c) 2013 RDCWorld. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<UICollectionViewDataSource, UICollectionViewDelegate>

@property (weak, nonatomic) IBOutlet UICollectionView *myCollectionView;

@property (nonatomic, retain) NSMutableArray *contentArray;

@end
-----------------------------------------------------------------------------------------------------------------------------------------


Now come to ViewController.m file , open it

1. add synthesize (for all declared variable in header file with @property) just below to @implementation

@synthesize myCollectionView;
@synthesize contentArray;

2. in viewDidLoad method

2.1 Initialize our content array and put the data into it.

    contentArray = [[NSMutableArray alloc] init];
    for (int i=0; i<100; i++) {
        [contentArray addObject:[NSString stringWithFormat:@"Cell %d",i]];
    }

2.2 get the UICollectionViewCell's Nib file (.xib file) here

UINib *cellNib = [UINib nibWithNibName:@"MyCell" bundle:nil];
    [myCollectionView registerNib:cellNib forCellWithReuseIdentifier:@"cvCell"];

2.3 create FlowLayout for collection view with its item size

    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
    [flowLayout setItemSize:CGSizeMake(100, 100)];

2.4 add scroll direction (in this we want as Horizontal scroll)

[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];

2.5 add FlowLayout to our Main collectionView

[myCollectionView setCollectionViewLayout:flowLayout];


3. Now Heart of the Application : we need to implement UICollectionView's Datasource & Delegate method
Note : we have already declared these protocols in header file and Hooked up with Layout.

Here we have some optional and mandatory methods, I will mention
at the end of file but before @end add these methods

// DataSource - optional method
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
    return 1;
}

// DataSource - mandatory methods
-(NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return [contentArray count];
}


-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {    
    NSString *cellData = [contentArray objectAtIndex:indexPath.row];    
    static NSString *cellIdentifier = @"cvCell";    
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];    
    UILabel *titleLabel = (UILabel *)[cell viewWithTag:100];    
    [titleLabel setText:cellData];    
    return cell;    
}

// Delegate - optional method
-(void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    
    NSString *cellData = [contentArray objectAtIndex:indexPath.row];
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:[NSString stringWithFormat:@"You have selected %@ item",cellData] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
    [alert show];
    
}

So Finally our ViewController.m file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  ViewController.m
//  CollectionViewDemo
//
//  Created by RDC on 3/6/13.
//  Copyright (c) 2013 RDCWorld. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController

@synthesize myCollectionView;
@synthesize contentArray;

#pragma mark - ViewController's Life Cycle methods

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //initialize array and put data on it
    contentArray = [[NSMutableArray alloc] init];
    for (int i=0; i<100; i++) {
        [contentArray addObject:[NSString stringWithFormat:@"Cell %d",i]];
    }
    
    //get the cell nib we have created
    UINib *cellNib = [UINib nibWithNibName:@"MyCell" bundle:nil];
    [myCollectionView registerNib:cellNib forCellWithReuseIdentifier:@"cvCell"];
    
    //create flow layout
    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
    [flowLayout setItemSize:CGSizeMake(100, 100)];
    [flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    
    //add flow layout to our collection view
    [myCollectionView setCollectionViewLayout:flowLayout];
    
    //optional : if you didn't hook up Datasource and delegate with File owner, you can use this
    //myCollectionView.dataSource = self;
    //myCollectionView.delegate=self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    
}

#pragma mark - UICollectionView DataSource methods


// DataSource - optional method
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
    return 1;
}

// DataSource - mandatory methods
-(NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return [contentArray count];
}


-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    
    NSString *cellData = [contentArray objectAtIndex:indexPath.row];
    static NSString *cellIdentifier = @"cvCell";    
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];    
    UILabel *titleLabel = (UILabel *)[cell viewWithTag:100];    
    [titleLabel setText:cellData];    
    return cell;    
}

#pragma mark - UICollectionView Delegate method

// Delegate - optional method
-(void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    
    NSString *cellData = [contentArray objectAtIndex:indexPath.row];
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:[NSString stringWithFormat:@"You have selected %@ item",cellData] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
    [alert show];
    
}

@end
-----------------------------------------------------------------------------------------------------------------------------------------


Make sure your AppDelegate file code should be default 

Finally our AppDelegate.h file look like 

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  AppDelegate.h
//  CollectionViewDemo
//
//  Created by RDC on 3/6/13.
//  Copyright (c) 2013 RDCWorld. All rights reserved.
//

#import <UIKit/UIKit.h>

@class ViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) ViewController *viewController;

@end
-----------------------------------------------------------------------------------------------------------------------------------------


Finally our AppDelegate.m file look like 

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  AppDelegate.m
//  CollectionViewDemo
//
//  Created by RDC on 3/6/13.
//  Copyright (c) 2013 RDCWorld. All rights reserved.
//

#import "AppDelegate.h"

#import "ViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

//for now leave rest all empty methods..

@end
-----------------------------------------------------------------------------------------------------------------------------------------


Okay wrap it up this application. let's Run it.

Here is the output 




Cheers!! we did it. It was so simple because Apple did everything for us.
we just made it alive.

You can find complete project source code zip file here : CollectionViewDemo.zip (73.94 KB)


I Would love to here your thoughts !! 

Tuesday, March 5, 2013

CollectionView in iOS 6 (Complete Theory)


The Collection View have been introduced as part of iOS 6. 



Why we need UICollectionView?

For years , iOS developers have used the UITableView component to create a huge variety of interfaces.

But still if you want to present data in multiple columns, for example, you need to combine entire rows of data into a single cell.
There is no way to make a UITableView scroll its content horizontally.

Well, apparently Apple realized this too, iOS 6 includes a new class called UICollectionView that is built to address theses shortcomings, Like a table view, this class lets you display a bunch of "cells" of data and will handle things like queueing up unused cells for later use. UICollectionView uses a halter class to do layout.

At the abstract level, a collection view consists of four key elements
1. Cells
2. Supplementary Views
3. Decoration Views
4. Layout Object

Cell : A cell is a representation of an item of data to be displayed (for example an image or a set of text based data).

Supplementary Views : Supplementary views are objects that provide additional information about a section in a collection view. These are somewhat similar to section headers and footers in table views but are more general purpose and provide a greater level of flexibility in terms of positioning and content.

Decoration Views : Decoration views can be used to provide a decorative background for the collection view which scrolls along with the content.
Note - Standard Flow layout class does not support decoration views.

So, Mainly three requirement for UICollectionView

1. UICollectionViewDataSource
2. UICollectionViewDelegate
3. UICollectionViewFlowLayout

UICollectionViewDataSource : The collection view instance needs a data source object from which to obtain the data items to be displayed.

UICollectionViewDelegate : The collection view instance needs a delegate object to handle user interaction with the collection.

UICollectionViewFlowLayout : The most important requirement for the UICollectionView class is a layout object to control the layout and organization of the cells.
By default, the UICollectionViewFlowLayout class is used by instances of the UICollectionView class.

Some Important classes and protocols for UICollectionView
1. UICollectionView class
2. UICollectionViewCell class
3. UICollectionViewFlowLayout class
4. UICollectionViewLayoutAttributes class
5. UICollectionViewDataSource protocol
6. UICollectionViewDelegate protocol
7. UICollectionViewFlowLayout protocol

1. UICollectionView  : The UICollectionView class is responsible for managing the data items that are to be displayed to the user.

2. UICollectionViewCell : UICollectionViewCell class is responsible for displaying whatever data is provided to the UICollectionView instance by the data source with one cell corresponding to one data item.
It has three parts 
2.1 Content View
2.2 SelectedBackground View
2.3 Background View



3. UICollectionViewFlowLayout  : The UICollectionViewFlowLayout class is the default layout class for collection views and is designed to layout cells in a grid-like manner.
By default, flow is implemented in a manner similar to that of “line wrapping” in a text editor.When one row of cells is full, the cells flow onto the next row and so on until all cells capable of fitting into the currently visible display region are visible. The flow layout class supports both horizontal and vertical scrolling configurable via the scrollDirection property. also supports the spacing between lines of cells in the grid.

4. UICollectionViewLayoutAttributes : Each item in a collection view has associated with it a set of attributes, below listed some important attributes
  • alpha – the transparency of the item.
  • center – the location of the center of the item.
  • frame – the CGRect frame in which the item is displayed.
  • hidden – whether or not the item is currently visible.
  • indexPath – the index path location of the item in the collection view.
  • representedElementCategory – The type of item for which the attributes apply (i.e. for a cell, supplementary or decoration view).
  • size – the size of the item.
  • transform3D – the current transform of the item. Attribute can be used to perform tasks such as rotating or scaling the item.
  • zIndex – controls the position of the item in the z axis


5. UICollectionViewDataSource : The UICollectionViewDataSource protocol needs to be implemented by the class responsible for supplying the collection view. This  basically consists of a number of methods that define information such how many items of data are to be displayed, how the data is divided into different sections and, most importantly, supplies the collection view with the cell objects to be displayed.
below listed some important methods
Mandatory Methods

  • collectionView:numberOfItemsInSection: - Returns the number of items to be displayed in the specified section of the collection view.
  • collectionView:cellForItemAtIndexPath : This method is called by the collection view when it is ready to display a cell at the specified index path location in the collection view. It is required to return a cell object configured appropriately for the referenced index.

Optional methods

  • numberOfSectionsInCollectionView: - Indicates to the collection view the number of sections into which the collection view is to be divided.
  • collectionView:viewForSupplementaryElementOfKind:atIndexPath :Called by the collection view to request a supplementary view of the specified kind. Returns an appropriately configured object to be displayed. In terms of the UICollectionViewFlowLayout class, the layout will request a supplementary view for either a header (UICollectionElementKindSectionHeader) or footer (UICollectionElementKindSectionFooter).

6. UICollectionViewDelegate : The UICollectionViewDelegate protocol defines a set of optional methods relate primarily to handling user interaction with the collection view elements (such as selecting a specific cell).
below listed some important methods
  • collectionView:shouldSelectItemAtIndexPath: - Returns a boolean value indicating whether the specified item is selectable by the user.
  • collectionView:didSelectItemAtIndexPath: - Called by the collection view when the specified item has been selected by the user.
  • collectionView:shouldDeselectItemAtIndexPath: - Returns a boolean value to indicate whether the specified item may be deselected by the user.
  • collectionView:didDeselectItemAtIndexPath: - Called by the collection view when the specified item has been selected by the user.
  • collectionView:shouldHighlightItemAtIndexPath: - Returns a boolean value indicating whether the specified item should be highlighted as a pre-cursor to possible selection by the user.
  • collectionView:didHighlightItemAtIndexPath: - Called by the collection view when the specified item has been highlighted.
  • collectionView:didUnhighlightItemAtIndexPath: - Called by the collection view when the specified item has been un-highlighted.
  • collectionView:didEndDisplayingCell:forItemAtIndexPath: - Called by the collection view when the specified cell has been removed from the collection view.
  • collectionView:didEndDisplayingSupplementaryView:forElementOfKind:atIndexPath: - Called by the collection view when the specified supplementary view has been removed from the collection view.

7. UICollectionViewFlowLayout : The UICollectionViewFlowLayout class has a number of properties that can be set to globally set default characteristics for items within a collection view (for example item spacing, line spacing, inter-cell spacing, supplementary view header and footer sizing etc).
below listed some important methods
  • collectionView:layout:sizeForItemAtIndexPath: - Required to return to the flow layout object the size attributes for the item at the specified index path.
  • collectionView:layout:insetForSectionAtIndex: - Required to return the inset value for the specified collection view section.
  • collectionView:layout:minimumLineSpacingForSectionAtIndex: - Required to return the inset value for the specified collection view section.
  • collectionView:layout:minimumInteritemSpacingForSectionAtIndex: - Required to return the interim spacing between cells in a row for the specified collection view section.
  • collectionView:layout:referenceSizeForHeaderInSection: - Required to return the size for the header supplementary view for specified collection view section. Note that if a size is not specified, the view will not appear.
  • collectionView:layout:referenceSizeForFooterInSection: - Required to return the size for the footer supplementary view for specified collection view section. Note that if a size is not specified, the view will not appear.

So this is what Apple guys added new Lib class added for iOS developer

You may love to go for Simple Tutorial for UICollectionView I have created for beginner.
or soon I'll add Advance UICollectionView Tutorial here, so stay tune with me :)

I would love here your thoughts!!