Can't Get Data Loaded on First Row of UITableView - objective-c

I'm trying to parse an HTML Data using HTMLParser (by Ben Reeves) and display results on UITableView. For some reasons I'm able to show up results only on last row of the tableView. Here's the code snippet:
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSData *responseData = [request responseData];
NSError *error = [request error];
HTMLParser *parser = [[HTMLParser alloc] initWithData:responseData error:&error];
HTMLNode *bodyNode = [parser body];
arrayNodes = [bodyNode findChildrenWithAttribute:#"class" matchingName:#"foo" allowPartial:NO];
for (HTMLNode *arrayNode in arrayNodes) {
NSString *footitle = [arrayNode allContents];
NSLog(#"%#", footitle);
fooLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 200, 30)];
fooLabel.text = (#"%#", footitle);
fooLabel.textColor = [UIColor blackColor];
}
[self.fooTableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [arrayNodes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
// Configure the cell.
// [self.arrayNodes objectAtIndex:indexPath.row];
[cell.contentView addSubview:fooLabel];
return cell;
}
Where am I making the mistake?

for (HTMLNode *arrayNode in arrayNodes) {
NSString *footitle = [arrayNode allContents];
NSLog(#"%#", footitle);
fooLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 200, 30)];
fooLabel.text = (#"%#", footitle);
fooLabel.textColor = [UIColor blackColor];
}
You are creating fooLabel's with same Frame size and location as many as arrayNodes array.
then in [cell.contentView addSubview:fooLabel]; it is showing you the last value that label is updated with.
take out that fooLabel from for loop.
in your cellForRowAtIndexPath:
HTMLNode* arrayNode = [arrayNodes objectAtIndex:[indexPath row]];
cell.textLabel.text = [NSString stringWithFormat:#"%#",[arrayNode allContents]];

You need to create the foolabel in your cellForRowAtindexPath method. Right now only one foolabel is created, and it is applied to each cell in turn and then set to the next cell, leaving it placed on the last cell. So instead you should do this:
-
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
// Configure the cell.
HTMLNode *arrayNode = [arrayNodes objectAtIndex:indexPath.row];
NSString *footitle = [arrayNode allContents];
UILabel *fooLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 200, 30)];
fooLabel.text = (#"%#", footitle);
fooLabel.textColor = [UIColor blackColor];
[cell.contentView addSubview:fooLabel];
[fooLabel release];
return cell;
}

Related

Adding label color close to each row in UITableView Objective-C

I have a UITableView with different sections and rows. I want to have different label or image like a icone close each cell but I don't know why it's looks like this picture:
Also scrolling changed the size of labels!
Here is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *key = [[self sectionKeys] objectAtIndex:[indexPath section]];
NSArray *contents = [[self sectionContents] objectForKey:key];
NSString *contentForThisRow = [contents objectAtIndex:[indexPath row]];
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
if(indexPath.row == 0)
{
UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(3,0,40,40)];
label.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview:label];
}
else if(indexPath.row == 1)
{
UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(3,0,40,40)];
label.backgroundColor = [UIColor redColor];
[cell.contentView addSubview:label]; }
else if(indexPath.row == 2)
{
UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(3,0,40,40)];
label.backgroundColor = [UIColor redColor];
[cell.contentView addSubview:label]; }
else{
}
[[cell textLabel] setText:contentForThisRow];
return cell;
}
In your code when user scroll table, labels created many times! You must check if color label already exist in cell and then set color
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
int colorLabelTag = 9999;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// Because table cells are reusing we must check is label already in cell
UILabel* label = (UILabel *) [cell viewWithTag:colorLabelTag];
// If no - we create label
if (!label) {
UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(3,0,40,40)];
label.tag = colorLabelTag;
[cell addSubview:label];
}
if(indexPath.row == 0)
{
label.backgroundColor = [UIColor darkGrayColor];
}
else if(indexPath.row == 1)
{
label.backgroundColor = [UIColor redColor];
}
else if(indexPath.row == 2)
{
label.backgroundColor = [UIColor redColor];
}
[[cell textLabel] setText:contentForThisRow];
return cell;
Unless you want more cusotomizing than this there is no need for subclassing the cell.
Let me give it a try:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *key = [[self sectionKeys] objectAtIndex:[indexPath section]];
NSArray *contents = [[self sectionContents] objectForKey:key];
NSString *contentForThisRow = [contents objectAtIndex:[indexPath row]];
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
// If you need to add more custom views then create them here. E.g.:
UILabel *myLable = [[UILabel alloc] initWithFrame:CGRectMake(10,200,20,20)];
myLable.text = #"Some Value";
label.tag = 101; // use anything but 1. Better use a constant expression.
[cell.contentView addSubview:myLable];
}
switch (indexPath.row) {
case 1:
cell.imageView.image = [UIImage imageNamed:#"red.png"];
break;
case 2:
cell.imageView.image = [UIImage imageNamed:#"blue.png"];
break;
case 3:
cell.imageView.image = [UIImage imageNamed:#"green.png"];
break;
}
UILabel* theLabel = (UILabel *) [cell viewWithTag:101]; // again, a constant is of better style here.
if (theLabel { // it must exist. However, it is good practice to check upon that.
label.text = #"someOtherValue";
}
[[cell textLabel] setText:contentForThisRow];
// you may need to layout your subviews here.
return cell;
}

Making UITableView without IB

I'm making UITableView without IB.
My UITableView has 2 styles UITableViewCell - first row style and other row style.
I use MTLable Class instead of UILabel.
Question:
This code's results is very strange.
First cell style and other cell style is mixed when next page scrolled.
I can't find my code's faults.
I need your advice. Thanks!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
//firsT cELL
if(indexPath.row==0)
{
CGRect frame=CGRectMake(0,0,80, 60);
MTLabel *label1=[[MTLabel alloc] init];
label1.backgroundColor = [UIColor grayColor];
label1.frame=frame;
label1.text=#"123";
label1.tag = 1001;
[cell.contentView addSubview:label1];
label1.autoresizingMask = UIViewAutoresizingFlexibleTopMargin &UIViewAutoresizingFlexibleWidth & UIViewAutoresizingFlexibleLeftMargin & UIViewAutoresizingFlexibleRightMargin;
label1.contentMode = UIViewContentModeTopLeft;
[label1 setTextAlignment:MTLabelTextAlignmentRight];
[label1 release];
}
else
{
CGRect frame3=CGRectMake(0,0,80, 60);
MTLabel *label3=[[MTLabel alloc]init];
label3.frame=frame3;
label3.backgroundColor = [UIColor purpleColor];
label3.text=#"100";
label3.tag = 1003;
label3.autoresizingMask = UIViewAutoresizingFlexibleTopMargin &UIViewAutoresizingFlexibleWidth & UIViewAutoresizingFlexibleLeftMargin & UIViewAutoresizingFlexibleRightMargin;
label3.contentMode = UIViewContentModeTopLeft;
[label3 setTextAlignment:MTLabelTextAlignmentRight];
[cell.contentView addSubview:label3];
[label3 release];
}
}
FTS_book *book = [items objectAtIndex:indexPath.row];
if(indexPath.row==0)
{
MTLabel *label1 = (MTLabel*)[cell viewWithTag:1001];
label1.text= [NSString stringWithFormat:#"%d", book.chapter];
}
else
{
MTLabel *label3 = (MTLabel*)[cell viewWithTag:1003];
label3.text= [NSString stringWithFormat:#"%d", book.verse];
}
return cell;
}
Use different cell Id's for those two styles.

Pushing data from one View to another

I have a table list of promotions held in an NSSet which I load into an array for the purpose of displaying the title/name on the cell. However I want to use the didselectrow method to push the selected promotion onto an individual promotion page. I've making promo.featuredArray = self.featuredArray however it doesn't seem to be passing the data. My code is as follows.
Promo list.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
Featured*featured = [self.featuredArray objectAtIndex:indexPath.row];
cell.textLabel.text = featured.details;
cell.textLabel.textColor = [UIColor whiteColor];
cell.detailTextLabel.text = self.place.name;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Promo * promo= [[Promo alloc] initWithNibName:#"Promo" bundle:nil];
//Featured*featured = [self.featuredArray objectAtIndex:indexPath.row];
promo.featuredArray = self.featuredArray;
[self.navigationController pushViewController:promo animated:YES];
[promo release];
//[featured release];
}
Promo.m
#synthesize featuredArray, featured = __featured;
- (void)viewDidLoad
{
self.clearImage = [UIImage imageNamed:#"fav_icon.png"];
self.clearImagePressed = [UIImage imageNamed:#"fav_icon_sel.png"];
Featured*featured = [self.featuredArray init];
self.name.text = [NSString stringWithFormat:#"%#", __featured.name];
self.time.text = [NSString stringWithFormat:#"%#", __featured.time];
// self.description.text = [NSString stringWithFormat:#"%#", __featured.description];
self.placeName.text = [NSString stringWithFormat:#"%#", __featured.Place];
[super viewDidLoad];
if([__featured.imageURL hasPrefix:#"http"])
{
[self getImageForPlace];
}
// else
// {
// [self refreshImage];
// }
//
self.title = #"Promotion";
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"background_texture.png"]];
self.view.backgroundColor = background;
[background release];
[featured release];
}
It's probably this line:
Featured*featured = [self.featuredArray init];
This is wrong in many ways.
Making this a community wiki because I don't have time to write a full answer.

When scrolling a tableview back again cells appear blank?

After loading a tableview with custom cells all looks fine and scrolling down is fine.
When I scroll up the cells above appear blank. They are in fact fully functional as they can still be selected and then they go off to the details pages.
The code cellForRowAtIndexPath is executed for the returning row and returns the cell as I would expect with the right details. It just isn't displayed.
Any thoughts/help would be appreciated.
The code below is what I have been using.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CustomCellIdentifier = #"CustomCellIdentifier";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
for (id oneObject in nib) {
if ([oneObject isKindOfClass:[CustomCell class]]) {
cell = (CustomCell *)oneObject;
}
}
}
// Configure the cell.
Book *aBook = [appDelegate.sortedArray objectAtIndex:indexPath.row];
//name
NSString *trimmedString = [aBook.Name stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
cell.nameLabel.text = trimmedString;
//catagory
NSString *trimmedExperience = [aBook.PrimaryExperience stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([trimmedExperience isEqualToString:#"1"]) {
cell.catagoryLabel.text = #"None";
}
else if([trimmedExperience isEqualToString:#"2"]){
cell.catagoryLabel.text = #"Limited";
}
else if ([trimmedExperience isEqualToString:#"4"]) {
cell.catagoryLabel.text = #"Full";
}
else {
cell.catagoryLabel.text = #"";
}
cell.distanceLabel.text = [NSString stringWithFormat:#"%1.1f",aBook.distance];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
The problem lies with the xib file and how it loaded. To cut out the issue and gain total control the following code was substituted for the IB version of the custom cell.
static NSString *CellTableIdentifier = #"CellTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellTableIdentifier] autorelease];
CGRect nameLabelRect = CGRectMake(15, 5, 200, 15);
UILabel *nameLabel = [[UILabel alloc] initWithFrame:nameLabelRect];
nameLabel.textAlignment = UITextAlignmentLeft;
nameLabel.font = [UIFont boldSystemFontOfSize:14];
nameLabel.tag = kNameTag;
[cell.contentView addSubview:nameLabel];
[nameLabel release];
CGRect catagoryLabelRect = CGRectMake(15, 26, 100, 15);
UILabel *catagoryLabel = [[UILabel alloc]initWithFrame:catagoryLabelRect];
catagoryLabel.textAlignment = UITextAlignmentLeft;
catagoryLabel.font = [UIFont systemFontOfSize:12];
catagoryLabel.tag = kExperienceTag;
[cell.contentView addSubview:catagoryLabel];
[catagoryLabel release];
CGRect distanceLabelRect = CGRectMake(210, 26, 70, 15);
UILabel *distanceLabel = [[UILabel alloc] initWithFrame:distanceLabelRect];
distanceLabel.textAlignment = UITextAlignmentRight;
distanceLabel.font = [UIFont boldSystemFontOfSize:12];
distanceLabel.tag = kDistanceTag;
[cell.contentView addSubview:distanceLabel];
[distanceLabel release];
}
Thanks for helping think this one through. Now the scrolling works perfectly.

adding different UILabel to each cell in UITableView

I'm adding different text to each cell in UITableView. However when I do that, test is displayed in every cell except for the first one..So if theres an array with 9 numbers between 1 to 9, 1 is displayed in the second cell, 2 is displayed in the third cell and respectively. There's nothing shown in the first cell fromHeres the codes
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
//cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell = [self getCellContentView:CellIdentifier];
}
if (indexPath.row == 0) {
NSLog(#"hi");
}
//add another textfield
NSString *path = [[NSBundle mainBundle] pathForResource:#"Rankvalue" ofType:#"plist"];
NSMutableArray* rank = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSString *rankValue = [rank objectAtIndex:indexPath.row];
UILabel *rankLabel = (UILabel *)[cell viewWithTag:1];
rankLabel.text = rankValue;
[rankLabel setFont:[UIFont fontWithName:#"austin power" size:[#"40" intValue]]];
CGRect labelFrame = CGRectMake(220,70,50,40.0);
[rankLabel setFrame:labelFrame];
// Configure the cell(thumbnail).
cell.textLabel.text = [self.stars objectAtIndex:indexPath.row];
NSString *path2 = [[NSBundle mainBundle] pathForResource:#"Filename" ofType:#"plist"];
self.filename = [[NSMutableArray alloc] initWithContentsOfFile:path2];
cell.imageView.image = [UIImage imageNamed:[self.filename objectAtIndex:indexPath.row]];
//transparent cell
cell.backgroundColor = [UIColor clearColor];
[rankLabel release];
[rankValue release];
return cell;
}
And this is the code for the subview of the cell
- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier {
CGRect CellFrame = CGRectMake(0, 0, 320, 65);
CGRect Label1Frame = CGRectMake(17,5,250,18);
UILabel *lblTemp;
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CellFrame reuseIdentifier:cellIdentifier] autorelease];
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
[lblTemp setFont:[UIFont fontWithName:#"Arial-Bold" size:15]];
lblTemp.tag = 1;
lblTemp.backgroundColor=[UIColor clearColor];
lblTemp.numberOfLines=0;
[cell.contentView addSubview:lblTemp];
return cell;
}
initWithFrame:reuseIdentifier: has been deprecated for initWithStyle:reuseIdentifier:
You should create one of the standard styles.
Set the values you want (font, etc.) on cell creation, not on refresh. Frame of text field is the same. And background color.
You really don't want to reload that plist (oh, there's two of them!) every time you refresh a cell! Load it once in another method and cache it as an ivar.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// create and set up all the layout attributes of the cell
// it should be auto released
// which should include a call like the following, or loading a cell from a nib
// cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
// reuseIdentifier:CellIdentifier];
// [cell autorelease];
}
// the only thing that should happen here is setting the data values
// into the cell!!!!!! All these values should be loaded once and
// kept as "model state" by the controller. Do not create an image
// each time through, do not load an entire plist to access one item
// each time through
rankLabel.text = rankValue;
cell.textLabel.text = [self.stars objectAtIndex:indexPath.row];
cell.imageView.image = [self imageAtRow:indexPath.row];
}
If the image your displaying is different for each cell, using imageNamed: is not appropriate. If there's 2 or 3 images that indicate type of cell that will each be used a lot, imageNamed: is likely preferable. imageWithContentsOfFile: is your other option, you'll need to build the full path
Try switching this:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
//cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell = [self getCellContentView:CellIdentifier];
}
for this:
UITableViewCell *cell=[self getCellContentView:CellIdentifier];
Not saying it will work, but just give it a shot. Also, do this inside your getCellContentView:
[lblTemp release]
Or you will have a leak.