How To Make An Interface With Horizontal Tables Like The Pulse News App: Part 2
This is a blog post by iOS Tutorial Team member Felipe Laso, an independent iOS developer and aspiring game designer/programmer. This is the second of a two-part series on how to create horizontal table views in an interface similar to the Pulse News App. If you haven’t already, check out part 1 of the tutorial […] By Ray Wenderlich.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How To Make An Interface With Horizontal Tables Like The Pulse News App: Part 2
50 mins
Creating The Article Cells
Right now we have vertical table view, and we have just created a custom UITableViewCell that has a horizontal table inside of it. But in order for our interface to be really cool we need another custom cell to put inside our horizontal table, let’s to that right now.
Create a subclass of UITableViewCell and name it ArticleCell, put it inside the global Classes folder in your project navigator. I will also let you do this part on your own as we have covered creating new classes and subclasses extensively in both parts of the tutorial (small challenges are good on our goal to become awesome iOS developers).
Now add all of this code to your ArticleCell.h file:
#import <UIKit/UIKit.h>
@interface ArticleCell : UITableViewCell
{
UIImageView *_thumbnail;
UILabel *_titleLabel;
}
@property (nonatomic, retain) UIImageView *thumbnail;
@property (nonatomic, retain) UILabel *titleLabel;
@end
We are creating a UIImageView to hold the thumbnail picture for our article and a UILabel that will have the title of our article. We also create the appropriate properties.
That’s it, now jump over to the ArticleCell.m file and delete all of the methods that Xcode added for us by default. Let’s now synthesize our properties, create the dealloc method and give our cell a reuse identifier, add the following code:
#import "ArticleCell.h"
@implementation ArticleCell
@synthesize thumbnail = _thumbnail;
@synthesize titleLabel = _titleLabel;
- (NSString *)reuseIdentifier
{
return @"ArticleCell";
}
- (void)dealloc
{
self.thumbnail = nil;
self.titleLabel = nil;
[super dealloc];
}
@end
We synthesize our properties as usual, we also release them in the dealloc method as we should. The only interesting bit going on is the reuseIdentifier method we added.
As you have probably seen, when we create a new UITableViewCell we pass in a reuse identifier so that instead of creating a new instance of a cell for each one we have on a table, we simply reuse those that are currently not being displayed.
In our case because we are using a custom UITableViewCell, we must manually define the reuse identifier which I have named ArticleCell for our project. This is very good practice as it will optimize the scrolling performance of your tables!
That’s it, now we have to create a subclass of ArticleCell for iPhone and iPad in order to override the initWithFrame method and customize the look of our cell.
Create a subclass of ArticleCell and name it ArticleCell_iPhone, place it within the Classes folder inside the iPhone folder, just so we keep things tidy as we have so far.
Leave the ArticleCell_iPhone.h header file empty as it is and delete all of the methods created for us inside the ArticleCell_iPhone.m implementation file. Once that is done go ahead and paste this code inside the implementation file:
#import "ArticleCell_iPhone.h"
#import "ControlVariables.h"
@implementation ArticleCell_iPhone
- (id)initWithFrame:(CGRect)frame
{
[super initWithFrame:frame];
self.thumbnail = [[[UIImageView alloc] initWithFrame:CGRectMake(kArticleCellHorizontalInnerPadding, kArticleCellVerticalInnerPadding, kCellWidth - kArticleCellHorizontalInnerPadding * 2, kCellHeight - kArticleCellVerticalInnerPadding * 2)] autorelease];
self.thumbnail.opaque = YES;
[self.contentView addSubview:self.thumbnail];
self.titleLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, self.thumbnail.frame.size.height * 0.632, self.thumbnail.frame.size.width, self.thumbnail.frame.size.height * 0.37)] autorelease];
self.titleLabel.opaque = YES;
self.titleLabel.backgroundColor = [UIColor colorWithRed:0 green:0.4745098 blue:0.29019808 alpha:0.9];
self.titleLabel.textColor = [UIColor whiteColor];
self.titleLabel.font = [UIFont boldSystemFontOfSize:11];
self.titleLabel.numberOfLines = 2;
[self.thumbnail addSubview:self.titleLabel];
self.backgroundColor = [UIColor colorWithRed:0 green:0.40784314 blue:0.21568627 alpha:1.0];
self.selectedBackgroundView = [[[UIView alloc] initWithFrame:self.thumbnail.frame] autorelease];
self.selectedBackgroundView.backgroundColor = kHorizontalTableSelectedBackgroundColor;
self.transform = CGAffineTransformMakeRotation(M_PI * 0.5);
return self;
}
@end
First off we import the ControlVariables.h header file, that’s so we can read in our constants without getting warnings or errors.
Next up we override the initWithFrame method with our custom one, we do the usual call to our super class’ initWithFrame method and inside it we put our custom code, so let’s go over each part one by one:
self.thumbnail = [[[UIImageView alloc] initWithFrame:CGRectMake(kArticleCellHorizontalInnerPadding, kArticleCellVerticalInnerPadding, kCellWidth - kArticleCellHorizontalInnerPadding * 2, kCellHeight - kArticleCellVerticalInnerPadding * 2)] autorelease];
self.thumbnail.opaque = YES;
[self.contentView addSubview:self.thumbnail];
We allocate and initialize a new UIImageView and give it a custom frame. As you will see we don’t position it at 0, 0 (the top left corner) but we give it a little bit of padding, as you remember a while back I told you this will allow for separation between each article cell.
Then we set the thumbnail as opaque, Apple recommends that all views are opaque when possible as it will greatly improve the performance of our UI.
After that we add the thumbnail as a subview of the cell’s content view, there’s a difference between adding it as a subview of the cell, and a subview of the cell’s content view!
self.titleLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, self.thumbnail.frame.size.height * 0.632, self.thumbnail.frame.size.width, self.thumbnail.frame.size.height * 0.37)] autorelease];
self.titleLabel.opaque = YES;
self.titleLabel.backgroundColor = [UIColor colorWithRed:0 green:0.4745098 blue:0.29019808 alpha:0.9];
self.titleLabel.textColor = [UIColor whiteColor];
self.titleLabel.font = [UIFont boldSystemFontOfSize:11];
self.titleLabel.numberOfLines = 2;
[self.thumbnail addSubview:self.titleLabel];
Moving on we create a UILabel and for the frame we make some adjustments so that it has some padding on the left side (thus preventing text to start from the very edge of the cell) and we make the height of the title label just 37% of the total height of the picture and we move it down a bit so it fits the bottom part of the cell.
This will make the title not cover the entire article cell and it’s image, but just the bottom half part. We then set the label as opaque, change the background color to a semitransparent gray, give it a white color for the text, set its font to the default bold font with a size of 11 points, allow the label to show in two lines and finally add it as a subview of the thumbnail.
Again, pretty standard stuff
self.backgroundColor = [UIColor colorWithRed:0 green:0.40784314 blue:0.21568627 alpha:1.0];
self.selectedBackgroundView = [[[UIView alloc] initWithFrame:self.thumbnail.frame] autorelease];
self.selectedBackgroundView.backgroundColor = kHorizontalTableSelectedBackgroundColor;
Up next we set the background color of the cell to something along the lines of our interface, we change the size of the cell’s background view to the same size as our thumbnail and give it the custom background color we added in our constants file earlier.
self.transform = CGAffineTransformMakeRotation(M_PI * 0.5);
Finally we just rotate the cell 90 degrees clockwise by using M_PI * 0.5. If you find this a bit off then let’s remember a few things, these cells will be inside the rotated table view so if we just pass them in as they are, we will see them rotated 90 degrees counter clockwise.
In order for us to see them properly we have to rotate them back so they appear normal.
As you can see making the interface is basic stuff, we just have to keep good track of which table is the vertical one and which one is the rotated horizontal table, and of course we have to keep track of our rotations and how things will show up in our interface.