How to customize the background color of the standard label within a UITableViewCell? - cocoa-touch

I'm trying for the past several hours to figure out how to do this, but with no luck. There are several potential solutions for this when searching Google, but nothing seems to work.
I'm trying to customize the background color of the standard UILabel that goes in a UITableViewCell (since I already customized the background color of the cell itself), but nothing I do seems to work.
I'm creating my own UILabel to customize the colors in -tableView:cellForRowAtIndexPath:
UILabel* label = [[[UILabel alloc] init] autorelease];
label.textColor = [UIColor blueColor];
label.backgroundColor = [UIColor redColor];
label.opaque = YES;
[cell.contentView addSubview:label];
cell.text = #"Sample text here";
But that doesn't work, and the resulting table view still has a bunch of cells with labels with black text and white background in it.
Any clues on what I am doing wrong here?
UPDATE: If I try to do the following instead:
UILabel* label = [[[UILabel alloc] init] autorelease];
label.textColor = [UIColor blueColor];
label.backgroundColor = [UIColor redColor];
label.opaque = YES;
[cell.contentView addSubview:label];
label.text = #"Sample text here";
I get a bunch of UITableViewCells with no text at all.

It appears that you're assigning the text to the cell instead of the label. You probably want:
label.text = #"Sample text here";
Also, you'll need to set the label's frame to what you require:
label.frame = CGRectMake(10,10, 80, 40);
or directly in the constructor:
label = [[UILabel alloc] initWithFrame:myFrame];

I wouldn't do this in code. I would do it with a custom XIB file and then load it in your
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
delegate function. That way you can design the XIB file to your exact specs, and tweak it.
Good luck!

You have asked this question before, and received correct answers;
How to customize the background color of a UITableViewCell?

Related

UINavigationBar setTitleTextAttributes

I'm trying to change the color of NavigationBars title while I'm on a viewcontroller (not before pushing it). by using:
[[[self navigationController] navigationBar] setTitleTextAttributes:textAttributes];
But this line of code only works before pushes or pops. I was wondering if there is a way to force this without navigating?
I would say the simplest way is to create an UILabel with the same style you want for the UINavigationController title and set the label to the navigationItem.titleView.
Try this one
UILabel * label = [[[UILabel alloc] initWithFrame:CGRectMake(0,0,45,45)] autorelease];
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor clearColor];
label.text = self.navigationItem.title;
self.navigationItem.titleView = label;
create custom label and set it as titleView of your navigation bar

UITableViewCell with UILabel subview caching issue

First of all, please don't tell me this is a duplicate. I know this question has been asked and answered many times but I still can't seem to get my code to work even after reading everyone else's solutions.
I'm having an issue with my UITableViewCell that contains a UILabel subview. The UILabel sometimes doesn't appear in certain cells until I scroll away from those cells and return to them. Here is the code I am using to customize the cells:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel *label;
if (cell == nil) {
// cell is nil, create it
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 33)];
label.tag = 888;
} else {
label = (UILabel*)[cell.contentView viewWithTag:888];
[label removeFromSuperview];
}
label.text = #"Label Text";
label.backgroundColor = [UIColor clearColor];
[label sizeToFit];
label.center = CGPointMake(cell.contentView.frame.size.width-label.frame.size.width/2-20, cell.contentView.frame.size.height/2);
[cell.contentView addSubview:label];
// customize cell text label
cell.textLabel.text = #"Cell Text";
cell.textLabel.textColor = [UIColor darkGrayColor];
return cell;
}
It appears as though the label shows up correctly when dequeueReusableCellWithIdentifier:CellIdentifier returns a non nil value but does not show up if the return value is nil and a new cell must be instantiated.
If anyone has an idea of why this might be happening, help would be greatly appreciated.
I see a couple of things you want to do.
1) read up on "sizeToFit" - the description says if the view has no superview you may get weird results.
2) When you create the view, add it to the cell immediately.
3) After you resize the cell, get its size, then compute the proper frame - I'd suggest not using "center" but I do not know that your code won't work for a fact.
4) Before even changing the center to changing the frame, hard code something like this:
CGRect r = label.frame;
r.origin = (CGPoint){ 20, 20 };
label.frame = r;
This will at least convince you that new cells and old cells are working properly. Then you can compute the frame you really want, or further play with center.
Not sure of the cause of your problem, but there are some improvements you could make. Maybe one of them fixes the issue:
In the dequeu scenario, you remove the label from the view, only to add it back. Instead, you should leave it in the view hierarchy.
To avoid having to resize and move the label all the time. Why not make it sufficiently wide, set the text right aligned. That way, you don't have to resize of move the label in the dequeue scenario.
It seems that the issue may be with modifying cell.textLabel. Other posts on this site have suggested that any time this label is modified, a new label is actually created and added to the cell's contentview (as opposed to just modifying the existing label). Setting cell.textLabel.backgroundColor = [UIColor clearColor]; seems to have fixed the problem
I'm still a bit confused about this though because even adding my custom label subview last (after setting properties for cell.textLabel) didn't fix the problem - the background color of cell.textLabel had to be set to transparent/clear.
There are three things out of place:
if (cell == nil) { // cell is nil, create it
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 33)];
label.tag = 888;
[cell.contentView addSubview:label]; // (1) DO THIS HERE
} else {
label = (UILabel*)[cell.contentView viewWithTag:888];
// (2) DON'T DO THIS: [label removeFromSuperview];
}
label.text = #"Label Text";
label.backgroundColor = [UIColor clearColor];
[label sizeToFit];
label.center = CGPointMake(cell.contentView.frame.size.width-label.frame.size.width/2-20, cell.contentView.frame.size.height/2);
// (3) DON'T DO THIS HERE: [cell.contentView addSubview:label];
....
I assume ARC is on, otherwise you need a [label release] after adding it to the contentView.

UITableViewCell background image

I have a small problem with the UITableviewCell. i'm using the code:
UIView *cellBackView = [[UIView alloc] initWithFrame:CGRectZero];
cellBackView.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed:#"Navigation.png"]];
cell.backgroundView = cellBackView;
But look what happend ;
http://cl.ly/070f1C3n143v0W1Y2g2Q
Somebody know how to fix it?
That is because of the labels that are in the way (in front of the background)
add this and it should be fixed
cell.textLabel.backgroundColor = [UIColor clearColor];

A More Concise Way to do This in Objective C?

So I have something like this in my code:
leftMostLabel = [[UILabel alloc] initWithFrame:CGRectMake(60.0f, 2.0f, 80.0f, 40.0f)];
leftMostLabel.text = #"Some text";
leftMostLabel.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
leftMostLabel.backgroundColor = [UIColor clearColor];
leftMostLabel.textAlignment = UITextAlignmentCenter;
leftMostLabel.font = [UIFont boldSystemFontOfSize:13.0];
leftMostLabel.userInteractionEnabled = NO;
centerLeftLabel = [[UILabel alloc] initWithFrame:CGRectMake(115.0f, 2.0f, 80.0f, 40.0f)];
centerLeftLabel.text = currentDate;
centerLeftLabel.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
centerLeftLabel.backgroundColor = [UIColor clearColor];
centerLeftLabel.textAlignment = UITextAlignmentCenter;
centerLeftLabel.font = [UIFont systemFontOfSize:12.0];
centerLeftLabel.userInteractionEnabled = NO;
Which is working fine and dandy, but I repeat that format many many times. I would ideally like to pass in the variable(leftMostLabel, centerLeftLabel, etc.) to a function which creates the labels for me behind the scenes based on the name of the variable that I pass to it, as well as whichever additional parameters I feed it. This possible? If so, how would I go about this?
Thanks in advance!
Objective-C offers the possibility to extend existing classes via categories, so you could easily add a method to UILabel such as: +labelWithFrame:text:textColor:backgroundColor:alignment:font:interaction:. That'd shorten things a bit, so your code would look like:
UILabel *leftLabel = [UILabel labelWithFrame:CGRectMake(...)
text:#"Yoo hoo!"
textColor:[UIColor blueColor]
backgroundColor:[UIColor clearColor]
textAlignment:UITextAlignmentLeft
font:[UIFont systemFontOfSize:12];
userInteractionEnabled:NO];
That's somewhat less cluttered looking and might be worthwhile.
If most of your labels are similar, another option would be to add a method that creates a label using a prototype. UIView's don't implement NSCopying, so you can't just make a copy of a label using the -copy method, but you can write a method that creates a new label and configures it based on an existing label. Calling it might look like:
UILabel *centerLabel = [UILabel labelWithFrame:CGRectMake(...)
likeLabel:leftLabel];
centerLabel.text = #"Hey there!";
Finally, consider using Interface Builder to create all these labels. Cocoa and Cocoa Touch code would be chock full of calls to view configuration methods like -initWithFrame: and -addSubview: if it weren't for IB. It may or may not be appropriate in your case, but sometimes people avoid IB because they think it's more work or makes their code more difficult to manage; I think the opposite is true.
Concise, there's a word you don't see too often in conjunction with Objective-C. Coming from another language I feel your pain with snippets like these.
I've resorted to writing the necessary label variations once, and then repeat them many times over. The other posted answers are all viable options, though I'm not so sure about the concise argument. #Caleb's 'likeLabel' answer is the most versatile, but you still need to be able to reference that other label.
I make a project-specific category on UILabel, and place the various labels in there my self. The only thing I'm comfortable repeating for every label is the frame and the text. There's not really a neccessity to put +methods in a category, but UILabel does sum up what you want quite nicely. After having the categories in place, this is how you'd use it:
UILabel *someLabel = [UILabel headerLabelWithFrame:CGRectMake(10, 10, 256, 32) andText:#"Conciseness"];
And this is what the category would look like with just one label type. You'd add more if needed:
#interface UILabel (ProjectSpecificLabels)
+(UILabel *)headerLabelWithFrame:(CGRect)frame andText:(NSString *)text;
#end
#implementation UILabel (ProjectSpecificLabels)
+(UILabel *)headerLabelWithFrame:(CGRect)frame andText:(NSString *)text {
UILabel *label = [[[self alloc] initWithFrame:frame] autorelease];
label.text = text;
label.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
label.font = [UIFont boldSystemFontOfSize:13.0];
label.userInteractionEnabled = NO;
return label;
}
#end
Hope it helps.
Cheers,
EP.
I would break it up into a function that sets my values.
leftMostLabel = [[UILabel alloc] initWithFrame:CGRectMake(60.0f, 2.0f, 80.0f, 40.0f)];
leftMostLabel.text = #"Some text";
[self initLabelValues:leftMostLabel withFont:[UIFont boldSystemFontOfSize:13.0]];
centerLeftLabel = [[UILabel alloc] initWithFrame:CGRectMake(115.0f, 2.0f, 80.0f, 40.0f)];
centerLeftLabel.text = currentDate;
[self initLabelValues:centerLeftLabel withFont:[UIFont boldSystemFontOfSize:12.0]];
-(void) initLabelValues:(UILabel*)inLabel withFont:(UIFont*)font {
[inLabel setTextColor:[UIColor colorWithWhite:1.0 alpha:1.0]];
[inLabel setBackgroundColor:[UIColor clearColor]];
[inLabel setTextAlignment:UITextAlignmentCenter];
[inLabel setUserInteractionEnabled:NO];
[inLabel setFont:font];
}

How Can I Set the Height of a Single UITabelViewCell to a Constant Value?

I am searching on Google about this but I always find very complex solutions about it. I have a cell with an non editable scrollable UITextView and I just want to increase the height of that cell to a constant value. How can I do it? Actually I am using the next code to add the UITextView to the cell.
cell.contentView.bounds = CGRectMake(0, 0, cell.frame.size.width, cell.frame.size.height);
UITextView *textView = [[UITextView alloc] initWithFrame:cell.contentView.bounds];
textView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
textView.editable = NO;
textView.scrollEnabled = YES;
textView.backgroundColor = [UIColor clearColor];
textView.text = self.description;
[cell.contentView addSubview:textView];
[textView release];
Thanks for reading.
Implement this method in your delegate: http://developer.apple.com/library/ios/documentation/uikit/reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:heightForRowAtIndexPath: