Hey all, I'm trying to create a business finder style app and was hoping to create a custom cell to display some information to the user. I've got the cell to display all the information I'm trying to give, but the format is off. Here is the code I'm using to create the cell.
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CustomCell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCellView" owner:self options:nil];
#ifdef __IPHONE_2_1
cell = (CustomCell *)[nib objectAtIndex:0];
#else
cell = (CustomCell *)[nib objectAtIndex:1];
#endif
}
// Configure the cell.
NSDictionary *dict = [rows objectAtIndex: indexPath.row];
cell.bizNameLabel.text = [dict objectForKey:#"name"];
cell.addressLabel.text = [dict objectForKey:#"address"];
NSMutableString *detailed = [NSMutableString string];
[detailed appendString:[dict objectForKey:#"distance"]];
[detailed appendString:#"mi"];
cell.mileageLabel.text = detailed;
// determine the rating for the business
NSString *icontype = [dict objectForKey:#"rating"];
NSInteger rating = [icontype intValue];
UIImage *image;
// variable to change the color of the cell's background
UIView *bg = [[UIView alloc] initWithFrame:cell.frame];
// switch statement to determine the rating image to be displayed
switch (rating) {
case 1:
{
image = [UIImage imageNamed:#"1.png"];
bg.backgroundColor = [UIColor yellowColor];
break;
}
case 3:
{
image = [UIImage imageNamed:#"3.png"];
bg.backgroundColor = [UIColor orangeColor];
break;
}
case 5:
{
image = [UIImage imageNamed:#"5.png"];
//bg.backgroundColor = [UIColor redColor];
cell.backgroundColor = [UIColor redColor];
break;
}
default:
break;
}
[cell.ratingImage setImage:image];
cell.backgroundView = bg;
[bg release];
#ifdef __IPHONE_3_0
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
#endif
return cell;
}
I then created the layout in IB to look like this..
(First 2 issues have been resolved, I was using the wrong image variable to display the image)
And when selected, you can tell things are out of whack
![enter image description here][3]
In IB I have the dimensions of the cell set at 320wide by 80high, and under the indentity tab, I've changed the class to CustomClass. I'm sure I'm overlooking something trivial, but if someone could throw me a bone, I'd be grateful. I've fixed the problem I was having with the image not displaying where I wanted it to, but I'm still having issues with the background color not changing, font size displaying different and when the cell is selected, it overlaps the cell separator.
Note: tried to include screen shots, but since I'm new SO wouldn't let me. I've provided a link where I've put the image of the selected cell that overlaps the separator below.
http://s1216.photobucket.com/albums/dd361/cabearsfan/?action=view¤t=screenshot2.png
Seems like you are not using your nib reference of the UIImageView but you are using the default imageView property of the cell.
I'd say there is a mis-match between the imageview frame and the size of the image you're giving it.
After your setImage call, add this code to find out what's going on:
NSLog(#" imageView frame %f,%f, %f, %f",imageView.frame.origin.x,imageView.frame.origin.y,
imageView.frame.size.width,imageView.frame.size.height);
NSLog(#" image size %f x %f", image.size.width, image.size.height);
Related
I have one UITableview and UICutsom cell. In that UITableview I populate data using web services. I change background color and font color of cell. When I scroll up and down of that Tableview cell background color and label color also change on another cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"FieldInventoryCell";
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
FieldInventoryCell *cell=(FieldInventoryCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
NSArray *nib=[[NSBundle mainBundle] loadNibNamed:#"FieldInventoryCell" owner:self options:nil];
cell=[nib objectAtIndex:0];
}
NSArray *ar = [[arr objectAtIndex:indexPath.row]componentsSeparatedByString:#"|"];
cell.Status.text=[ar objectAtIndex:1];
cell.serialnumber.text=[ar objectAtIndex:0];
cell.date.text=[ar objectAtIndex:2];
if([cell.serialnumber.text isEqualToString:#"Grand Total"])
{
cell.contentView.backgroundColor=[UIColor blueColor];
cell.serialnumber.textColor=[UIColor whiteColor];
}
if ([cell.serialnumber.text isEqualToString:#"INV_FLD Status Total"])
{
//cell.contentView.backgroundColor=[UIColor blueColor];
cell.serialnumber.textColor=[UIColor orangeColor];
}
return cell;
}
As far as I can understand from your post, the problem you're probably experiencing is connected with dequeuing cells. You're setting some colors for the contentView and the serial number label, but you're not resetting them if the conditions are not met. Since the table reuses cells, your already colored items will appear for new elements. To ammend the problem, reset the colors to default, i.e. something like
// ...
if([cell.serialnumber.text isEqualToString:#"Grand Total"])
{
cell.contentView.backgroundColor=[UIColor blueColor];
cell.serialnumber.textColor=[UIColor whiteColor];
} else {
// reset color
cell.contentView.backgroundColor=[UIColor clearColor];
cell.serialnumber.textColor=[UIColor blackColor];
}
if ([cell.serialnumber.text isEqualToString:#"INV_FLD Status Total"])
{
//cell.contentView.backgroundColor=[UIColor blueColor];
cell.serialnumber.textColor=[UIColor orangeColor];
} else {
// reset color
cell.serialnumber.textColor=[UIColor blackColor];
}
I have a table view loading in the below manner. If a condition is met I need to add a particular image above the cell.imageview. Also the images are coming in different dimensions. Below is my code can anybody point me in where i am going wrong.
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if(array==nil||[array count]==0)
{
}
else
{
NSMutableDictionary *dicttable=[array objectAtIndex:indexPath.row];
NSString *head=[dicttable objectForKey:#"name"];
NSString *type=[dicttable objectForKey:#"type"];
NSString *imgUrl = [dicttable objectForKey:#"image"];;
if(imgUrl!=nil)
{
if(![[ImageCache sharedImageCache] hasImageWithKey:imgUrl])
{
cell.imageView.image = [UIImage imageNamed:#"noimage_icon.png"];
NSArray *myArray = [NSArray arrayWithObjects:cell.imageView,imgUrl,#"noimage_icon.png",[NSNumber numberWithBool:NO],nil];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate performSelectorInBackground:#selector(updateImageViewInBackground:) withObject:myArray];
cell.imageView.frame=CGRectMake(0,0,48,48);
cell.imageView.bounds=CGRectMake(0,0,48,48);
[cell.imageView setClipsToBounds:NO];
}
else
{
cell.imageView.image = [[ImageCache sharedImageCache] getImagefromCacheOrUrl:imgUrl];
cell.imageView.frame=CGRectMake(0,0,48,48);
cell.imageView.bounds=CGRectMake(0,0,48,48);
[cell.imageView setClipsToBounds:NO];
}
}
else
{
cell.imageView.image = [UIImage imageNamed:#"noimage_icon.png"];
}
if([type isEqualToString:#"YES"])
{
UIImageView* img = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"bluel.png"]];
[cell setBackgroundView:img];
[img release];
cell.textLabel.text = head;
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.textColor=[UIColor grayColor];
cell.detailTextLabel.text = subtitle1;
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
}
else
{
UIImageView* img = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"wnew1.png"]];
[cell setBackgroundView:img];
[img release];
cell.textLabel.text = head;
cell.textLabel.backgroundColor = [UIColor clearColor];
[cell.imageView addsubview:spclimage]
cell.textLabel.text = head;
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.textColor=[UIColor grayColor];
cell.detailTextLabel.text = subtitle1;
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
}
}
return cell;
Here the problem is only in the last row the special image is adding. Not in all rows. Also the image view size is different in all the time the tableview is reloading?
A couple of thoughts:
The updateImageViewInBackground seems suspect, as the name suggests that you're updating an image view, but you don't specify which cell you're updating.
I also see you doing a addSubview:spclimage. Obviously, if that spclimage was on another cell, as soon as you do addSubview, it will be removed from the previous location before being added to current cell. In fact, just the notion of adding an image as a subview of an existing imageview is curious.
If your cache doesn't have the image yet, I see where you're initializing the image with noimage_icon.png, but I don't see where you're actually updating the image view. You say updateImageViewInBackground is "then updating the image". Do you mean setting the image property for the imageView for this cell for this indexPath? Or maybe updating spclimage? If so, that's problematic.
The typical pattern (using GCD) for this would be:
cell.imageView.image = [UIImage imageNamed:#"noimage_icon.png"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *image = ... // do whatever you need to do to get the image, load cache, etc.
// ok, now that you have the image, dispatch the update of the UI back to the main queue
dispatch_async(dispatch_get_main_queue(), ^{
// because we're doing this asynchronously, make sure the cell is still
// visible (it could have scrolled off and the cell was dequeued and
// reused), so we're going to ask the tableview for the cell for that
// indexPath, and it returns `nil` if it's not visible. This method is
// not to be confused with the similarly named `UITableViewControllerDelegate`
// method.
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// if the image view is still visible, update it
if (cell)
{
cell.imageView.image = image;
}
});
});
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier] autorelease];
}
timeLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 33)];
dataLabel = [[UILabel alloc]initWithFrame:CGRectMake(105, 0, 320, 33)];
timeLabel.backgroundColor = [UIColor clearColor];
dataLabel.backgroundColor = [UIColor clearColor];
dataLabel.textColor = [UIColor whiteColor];
timeLabel.textColor = [UIColor whiteColor];
[cell.contentView addSubview:timeLabel];
[cell.contentView addSubview:dataLabel];
if(indexPath.row == 0)
{
if([storedDataArray count]>0)
{
timeLabel.text = currenttime;
dataLabel.text = textView1.text;
}
return cell; //returns empty cell if there is no data in the data base
}
if(indexPath.row == 1)
{
timeLabel.text = currenttime;
dataLabel.text = textView2.text;
return cell;
}
I have a table view
- i want to display my textlabel on left side, just beside detailTextlabel.
actually when i use textLabel.text, DetailTextLabel.Text and alignments,
they displayed but not at the position i want.
so i tried to use own labels..
but they get overwritten.
since we did not (it's not possible to) change the possition & the frame size of the cell textlabel, detailTextLabel, i added 2 labels with a frame size that i want.
but when we entered text in text views and return back to table view.. the labels get overwritten..
what to do..
is there any alternate to fixed the frame size of my text label
or to avoid overwriting of our labels
Use Custom UITableViewCell instead. You can align and place labels easily using custom tabe cells.
This link will be helpful. http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7-SW1
look at the customizing section in the document.
use this code it will work perfectly
if (cell== nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MenuNameCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
NSLog(#"---------new cell agin");
}
else
{
NSArray *arrayView = [cell.contentView subviews];
for (UIView *vTemp in arrayView)
{
[vTemp removeFromSuperview];
}
NSLog(#"---No New Cell hiiii");
// Setting Tag To UIButton
_checkButton = (UIButton *)[cell.contentView viewWithTag:indexPath.row];
_cancelButton = (UIButton *)[cell.contentView viewWithTag:indexPath.row];
}
add else part only
I'm semi new to developing for iOS.
And when i try to customize a tableview cell to put an image under the description text, it works, until i scroll, then it gets all messed up.
When i scroll down, then back up, the image is in a cell it shouldn't be in. :/
I deleted the code because it wasn't working. But what i was doing was creating a UIView with a frame, with a UIImageView inside it. Then i add it to cell.contentView.
Which works, until i scroll.
So could someone please help :/
Edit: here is what it looks like for anyone interested, i got it working. (Thanks Jonathan)
#define LEVEL_TAG 1
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UIImageView *showLevel;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
showLevel = [[[UIImageView alloc] initWithFrame: CGRectMake(65, 50, 0, 11)] autorelease];
showLevel.tag = LEVEL_TAG;
[cell.contentView addSubview: showLevel];
} else {
showLevel = (UIImageView *)[cell.contentView viewWithTag:LEVEL_TAG];
}
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSArray *levelArray = [dictionary objectForKey:#"Levels"];
NSString *levelValue = [levelArray objectAtIndex:indexPath.row];
UIImage *levelImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource: levelValue ofType:#"png"]];
CGImageRef starImage = levelImage.CGImage;
NSUInteger levelWidth = CGImageGetWidth(starImage);
showLevel.frame = CGRectMake(65, 50, levelWidth, 11);
showLevel.image = levelImage;
return cell;
}
It's because of the way the tableView reuses old cells, rather than creating new ones every time the user scrolls, which would make everything slower, and less efficient.
Have a look at Listing 5-3 on the Apple Documentation about customizing UITableViewCells, it shows you how to set up the cell, within the if statement where the cell is actually created, and not where the cell could have been reused.
I made a grouped UITableView in iPhone OS 3.0 that looked like the left image. The result is the right image in OS 3.1.
The imageView is under the separators.
I've tried to put the content view in front. The separatorStyle propriety seems ignored when the tableView is in grouped style (to draw the separator myself). Changing the separator color gives strings results.
Thanks for your help!
Edit: This is the code with no change made :
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.font = [UIFont boldSystemFontOfSize:18.0];
}
cell.textLabel.text = [[metro.arretDirection objectAtIndex:indexPath.row] name];
NSString* name;
if (indexPath.row == 0) {
name = #"Begining";
}
else if (indexPath.row + 1 == [metro.arretDirection count]) {
name = #"End";
}
else {
if ([[[metro.arretDirection objectAtIndex:indexPath.row] lines] count]== 1) name = #"Little";
else name = #"Big";
}
UIImage* metroImage = [[UIImage alloc] initWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:[NSString stringWithFormat:#"%i%#.png", metro.metroNumber, name]]];
cell.imageView.image = metroImage;
[metroImage release];
return cell;
On the cell try setting clipsToBounds to NO. eg cell.clipsToBounds = NO;
The answer was actually quite simple, simply add an UIImageView in the cell an place it properly instead of using the built in imageView.