Make sure you have JSON Framework installed first.
This is a continuation of More Complex JSON endpoint
The reason why OOP is so powerful is that you can subclass everything to make it work or look just how you want it. The default look of a UITableViewCell is just one line of text. If you want to add some text below it you need to subclass that. So that is what we will do right now.
The first thing we want to do is create a new subclass in your project. You should know how to do this already. File -> New File and select a UITableViewCell subclass. I have named mine ImageCell
Now you can see we have the title in nice big letters and the URL to the image under in in smaller letters and also in grey
I am just going to paste all the code and I have made some comments to show you what I added
First your ImageCell.h should look like
#import @interface ImageCell : UITableViewCell { // adding the 2 labels we want to show in the cell UILabel *titleLabel; UILabel *urlLabel; } // these are the functions we will create in the .m file // gets the data from another class -(void)setData:(NSDictionary *)dict; // internal function to ease setting up label text -(UILabel *)newLabelWithPrimaryColor:(UIColor *)primaryColor selectedColor:(UIColor *)selectedColor fontSize:(CGFloat)fontSize bold:(BOOL)bold; // you should know what this is for by know @property (nonatomic, retain) UILabel *titleLabel; @property (nonatomic, retain) UILabel *urlLabel; @end
There really isn’t any magic going on in the header. So now open up the ImageCell.m file and my contents are as follows.
#import "ImageCell.h" @implementation ImageCell // we need to synthesize the two labels @synthesize titleLabel, urlLabel; - (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) { // Initialization code // we need a view to place our labels on. UIView *myContentView = self.contentView; /* init the title label. set the text alignment to align on the left add the label to the subview release the memory */ self.titleLabel = [self newLabelWithPrimaryColor:[UIColor blackColor] selectedColor:[UIColor whiteColor] fontSize:14.0 bold:YES]; self.titleLabel.textAlignment = UITextAlignmentLeft; // default [myContentView addSubview:self.titleLabel]; [self.titleLabel release]; /* init the url label. (you will see a difference in the font color and size here! set the text alignment to align on the left add the label to the subview release the memory */ self.urlLabel = [self newLabelWithPrimaryColor:[UIColor blackColor] selectedColor:[UIColor lightGrayColor] fontSize:10.0 bold:NO]; self.urlLabel.textAlignment = UITextAlignmentLeft; // default [myContentView addSubview:self.urlLabel]; [self.urlLabel release]; } return self; } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } /* this function gets in data from another area in the code you can see it takes a NSDictionary object it then will set the label text */ -(void)setData:(NSDictionary *)dict { self.titleLabel.text = [dict objectForKey:@"title"]; self.urlLabel.text = [dict objectForKey:@"img"]; } /* this function will layout the subviews for the cell if the cell is not in editing mode we want to position them */ - (void)layoutSubviews { [super layoutSubviews]; // getting the cell size CGRect contentRect = self.contentView.bounds; // In this example we will never be editing, but this illustrates the appropriate pattern if (!self.editing) { // get the X pixel spot CGFloat boundsX = contentRect.origin.x; CGRect frame; /* Place the title label. place the label whatever the current X is plus 10 pixels from the left place the label 4 pixels from the top make the label 200 pixels wide make the label 20 pixels high */ frame = CGRectMake(boundsX + 10, 4, 200, 20); self.titleLabel.frame = frame; // place the url label frame = CGRectMake(boundsX + 10, 28, 200, 14); self.urlLabel.frame = frame; } } /* this function was taken from an XML example provided by Apple I can take no credit in this */ - (UILabel *)newLabelWithPrimaryColor:(UIColor *)primaryColor selectedColor:(UIColor *)selectedColor fontSize:(CGFloat)fontSize bold:(BOOL)bold { /* Create and configure a label. */ UIFont *font; if (bold) { font = [UIFont boldSystemFontOfSize:fontSize]; } else { font = [UIFont systemFontOfSize:fontSize]; } /* Views are drawn most efficiently when they are opaque and do not have a clear background, so set these defaults. To show selection properly, however, the views need to be transparent (so that the selection color shows through). This is handled in setSelected:animated:. */ UILabel *newLabel = [[UILabel alloc] initWithFrame:CGRectZero]; newLabel.backgroundColor = [UIColor whiteColor]; newLabel.opaque = YES; newLabel.textColor = primaryColor; newLabel.highlightedTextColor = selectedColor; newLabel.font = font; return newLabel; } - (void)dealloc { // make sure you free the memory [titleLabel dealloc]; [urlLabel dealloc]; [super dealloc]; } @end
So now we can save that file and open up RootViewController.m
We need to add in a import
#import "ImageCell.h"
Now go down to the cellForRowAtIndexPath function. Right now we have a UITableViewCell *cell call to init the cell, we need to change that since we are using our new ImageCell class. So replace that line with
ImageCell *cell = (ImageCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
Also we need to replace the cell = line in the if (cell == nil) if statement
cell = [[[ImageCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
Now remove the cell.text line and replace it with the following
NSDictionary *itemAtIndex = (NSDictionary *)[self.jsonArray objectAtIndex:indexPath.row]; [cell setData:itemAtIndex];
Now you can build and go and you should get the following
As you can see you now have the title in nice big letters and the URL in smaller gray letters below the title. As always you can grabt he source code here.