CCTableViewSuite

Article contributed by saim80

Introduction to CCTableViewSuite

Table view is an essential part of UIKit. Most app uses it to show data because of its efficient memory management and attractive scrolling experience. Even, in game development, table view is often required, i.e., device list for network play, list of settings/options, and level boards. To meet such requirements, developers either need to write their own table implementation or need to use UITableView. Using UITableView often causes extra efforts to create separate classes and code, mixing it with Cocos2d code. In addition, it cannot take advantage of any Cocos2d features because it is not a subclass of CCNode. Due to this motivation, I decided to port my table view implementation that was based on UIKit a while ago. As it is the first draft for Cocos2d, I decided to port only the essential part that closely assimilates UITableView’s behavior.
In the following sections, I will discuss features and limitations of CCTableView and how to use it.
You can download this project from:

Features and Limitations of CCTableView Classes

CCTableViewSuite consists of three classes: CCScrollView, CCTableView, and CCMultiColumnTableView.
CCScrollView is a subclass of CCLayer and super class of all table classes. It performs the following tasks:
  • Content clipping
  • Auto-scrolling by flick-and-release
  • Bouncing
  • Three scroll direction types: vertical, horizontal, and both
  • Generating scroll event messages via delegate
CCScrollView is very similar to UIKit’s UIScrollView but it does not provide zooming and scroll lock. CCScrollView requires you to modify CCNode’s visit method. Please read ‘How To’ section for the details.
You must not add another CCScrollView as its content if you enabled boundary clipping. CCScrollView uses OpenGL clipping planes, from plane0 to plane3, to cut its visible bounds. OpenGL provides a finite number of clipping planes while CCNode allows infinite number of CCNode objects to be added as its descendants regardless of the depth.
The current implementation supports only cpp(0.0f, 0.0f) as anchor points for the table itself and its content. For the content, It is automatically set when one of addChild: methods are called.
CCTableView is a subclass of CCScrollView. It uses datasource and delegate protocols to do the following tasks:
  • Cell layout
  • Memory management for cells by enqueueing the hidden cells that are completely clipped by visible bounds, dequeueing cells.
  • Uses CCNode objects as data. So any cocos2d object can be used. You can take full advantage manipulating the table itself or its cells by Cocos2d library.
  • Touch detection for cells.
Due to the fact that CCTableView uses the left, bottom corner of the screen as its origin, it will fill cells from the left, bottom corner to the right, top corner.
Cell size won’t be detected automatically, and all cells must have the equal size. You need to override CCTableViewCell class to provide cell size. It is very possible to detect cell size and let them be different for a table. However, it requires for the table object to iterate all cells to compute its content size. Hence, it is not supported.
CCMultiColumnTableView is a subclass of CCTableView. It simply does one more thing, allowing cells to be aligned in multiple columns.

How To Use CCTableViewSuite

All classes’ interfaces are very similar to what you can find in UIKit and Cocos2d. However, You need to modify CCNode as the following or refer to the CCNode.m included in the download.

Modifying CCNode

This modification allows CCScrollView to clip its content. beforeDraw and afterDraw are overriden by CCScrollView class.

In CCNode.m,

-(void) beforeDraw
{}
-(void) draw
{}
-(void) afterDraw
{}
-(void) visit
{
	if (!visible_)
		return;

	glPushMatrix();

	if ( grid_ && grid_.active) {
		[grid_ beforeDraw];
		[self transformAncestors];
	}

	[self transform];
	[self beforeDraw];
	for (CCNode * child in children_) {
		if ( child.zOrder = 0 )
			[child visit];
	}
	[self afterDraw];
	if ( grid_ && grid_.active)
		[grid_ afterDraw:self];

	glPopMatrix();
}

Creating CCScrollView

// size defines the scroll view’s visible bounds
CCScrollView *view = [CCScrollView scrollViewWithViewSize:size];
CCSprite     *sprite = [CCSprite spriteWithFile”img.png”];
//setting positions, CCLayer’s anchorPoint is ccp(0.0f, 0.0f), screen origin.
sprite.position = ccp(0.0f, 0.0f);
view.position   = ccp(0.0f, 0.0f);
view.contentOffset = ccp(0.0f, 0.0f); // setting internal content container (CCLayer) position.
view.contentSize = sprite.contentSize;
[view addChild:sprite];
[self addChild:view];
You may want to modify properties, depending on your needs.

CCScrollView Properties

  • delegate generates DidScroll event. Table views will update its content during this event.
  • isDragging readonly. YES, if users is touching the view.
  • bounces Set it to YES to let scroll view to stop scrolling at the edges of its content. NO will let users to scroll its content up to predefined insets.
  • direction Scrolling direction: CCScrollViewDirectionVertical,CCScrollViewDirectionHorizontal, or CCScrollViewDirectionBoth.
  • clipToBounds Set it to NO will disable clipping. The content that exceeds the visible bounds will still be visible.
  • contentOffset The location of CCLayer object which acts as a container for the content. You can scroll programmatically by using this property or setContentOffset:animated: method.
  • viewSize determines visible bounds.
  • isEnabled enables/disables user interactions.

Defining Cell Size

@interface MyCell : CCTableViewCell {}
@end
@implementation MyCell
+(CGSize)cellSize {
   return CGSizeMake(?,?);
}@end

Creating CCTableView

CCTableView *myTable = [[CCTableView tableViewWithDataSource:self size:size];
myTable.position = ccp(0.0f, 0.0f);
myTable.tDelegate = [delegate]; //set if you need touch detection on cells.
[self addChild:table];
[table reloadData];

Implementing Delegates

@interface TableViewScene
:          CCLayer
#
           CCTableViewDelegate,
           CCTableViewDataSource
#
{
@private
   CCTableView *myTable;
}
+(id)scene;
@end
@inplementation TableViewScene
//provide data to your table
//telling cell size to the table
-(Class)cellClassForTable:(CCTableView *)table {
   return [MyCell Class];
}
//providing CCNode object for a cell at a given index
-(CCTableViewCell *)table:(CCTableView *)table cellAtIndex:(NSUInteger)idx {
   CCTableViewCell *cell
   CCSprite	*sprite;
   cell = [table dequeueCell];
   sprite = //create a proper sprite for the index, idx.
   if (!cell) { //there is no recycled cells in the table
      cell = [[MyCell new] autorelease]; // create a new one
   }
   //configure the sprite.. do all kinds of super cool things you can do with cocos2d.
   cell.node = sprite;
   return cell;
}
-(NSUInteger)numberOfCellsInTableView:(CCTableView *)table {
   //return a number
}
//touch detection here
-(void)table:(CCTableView *)table cellTouched:(CCTableViewCell *)cell {
   //check if table is the one you expected.
   // if so, do something useful
   if (table == myTable && cell.idx == 0) {
      [cell.node runAction:cachedAction];
   }
}
@end

CCMultiColumnTableView

Do exactly what you would do for CCTableView. It will automatically adjust cell layout, depending on cell size and the table’s viewSize property. To control the number of columns manually, set colCount to a number you want and direction to CCScrollViewDirectionBoth.
This entry was posted in cocos2d and tagged , , , , . Bookmark the permalink.

35 Responses to "CCTableViewSuite"

Leave a reply


8 × = forty