Custom table view cell selection font color - ios

I have a custom UITableViewCell. It has 3 custom labels inside it with custom text.
When i tap on the cell, i want the textColor of all those labels to go white. just like Email app UITableViewCell behavior.
For that, I wrote this in the custom cell class.
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
if (self.selected) {
_subjectLabel.textColor = [UIColor whiteColor];
_messageLabel.textColor = [UIColor whiteColor];
_usernameLabel.textColor = [UIColor whiteColor];
}else {
_subjectLabel.textColor = [UIColor blackColor];
_messageLabel.textColor = [UIColor grayColor];
_usernameLabel.textColor = [UIColor blackColor];
}
}
I was able to get it. But its not as smooth as it is in the Email app. The color changes only after a small delay. Which method of UITableViewCell should I override to put this code in. I know about the below options, but they don't give the behavior onto custom labels in the custom cell.
typedef enum {
UITableViewCellSelectionStyleNone,
UITableViewCellSelectionStyleBlue,
UITableViewCellSelectionStyleGray
} UITableViewCellSelectionStyle;

Set the label's highlightedTextColor and this will all be done for you automatically. You should not have to do anything special in setSelected at all.
e.g.
_subjectLabel.highlightedTextColor = [UIColor whiteColor];

When we select any cell of UITableView , -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath method called immediately, you can use this.

Related

Dynamically changing textColor of a UITableViewCell's text

I have a custom UITableViewController that has one row, and only two UITableViewCells.
I'm trying to dynamically set the color of my UITableViewCell's text (cell.textLabel.textColor) based upon a few things:
1) If this is the first time launching, the first cell's text color should be [UIColor whiteColor], and the second cell's text color should be [UIColor grey1Color]
2) If the user selects a cell and leaves the screen and then returns to the table-view, the last selected cell's text color should be [UIColor whiteColor], and text color of the cell that was not selected should be [UIColor grey1Color].
Whenever a cell is selected, a property is updated; myCellTextValue. This is done to make a few API calls outside of this particular table-view.
My idea for implementing the logic above was to use this property for determining what color the cell's text should be. My code attempt below is in cellForRowAtIndexPath:
if (cell.textLabel.text == self.myCellTextValue) {
cell.textLabel.textColor = [UIColor whiteColor];
} else {
cell.textLabel.textColor = [UIColor grey1Color];
}
}
However, both cell's text color is always grey. I'm sure this mostly has to do with misunderstanding UITableViewCell creation in someway. Does anyone have any pointers on how to implement this properly? Thank you!
EDIT: Following #Gismay's comment below, I tried the code below; but got the same result:
if ([cell.textLabel.text isEqualToString:self.myCellTextValue]) {
cell.textLabel.textColor = [UIColor whiteColor];
} else {
cell.textLabel.textColor = [UIColor grey1Color];
}
EDIT 2: I also tried wrapping the code above in a check to make sure we're only looking at one cell at a time, but this had no effect either:
if((indexPath.section==0)&&(indexPath.row==0)){
if ([cell.textLabel.text isEqualToString:self.myCellTextValue]) {
cell.textLabel.textColor = [UIColor whiteColor];
} else {
cell.textLabel.textColor = [UIColor grey1Color];
}
} else if((indexPath.section==0)&&(indexPath.row==1)){
if ([cell.textLabel.text isEqualToString:self.myCellTextValue]) {
cell.textLabel.textColor = [UIColor whiteColor];
} else {
cell.textLabel.textColor = [UIColor grey1Color];
}
}
You can do something like:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//change your cell text color here
cell= [tableView cellForRowAtIndexPath:indexPath]
cell.textLabel.textColor = [UIColor whiteColor];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (cell.isSelected == YES)
{
cell.textLabel.textColor = [UIColor grey1Color];
}
else
{
cell.textLabel.textColor = [UIColor whiteColor];
}
}
Another way is to subclass the tableview cell and implement the following methods:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
[self updateTextColor:selected];
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
[self updateTextColor:highlighted];
}
- (void)updateTextColor:(BOOL)isSelected {
labelA= //get reference of the cell textlabel
if (labelA) {
if (isSelected) {
[labelA setTextColor:[UIColor whiteColor]];
} else {
[labelA setTextColor:[UIColor greyColor]];
}
}
}
you could use selectedRowIndex as a class-level variable, and just keep updating that every time you select a row. Initially - whether selected or not - this should be 0, so that the first row is different
I think you don't want to use the text value because it may not be unique
What happens when you make multiple selections without leaving the view? Presumably you need to clear the white text from the old row, and set it again on the new one?
Easiest way to implement that is going to be reloading the tableView on each selection - but if that takes too long, you could always reload the individual rows - on row selection set selectedRowIndexPrevious before you update selectedRowIndex, and reload both of those rows. The previous row will redraw in grey, and the new one in white
here's how you might implement some of this
class MyViewController : UIViewController
{
// define the variables to keep track of row selection here
var selectedRowIndex : Int = 0
var selectedRowIndexPrevious : Int = -1
// the rest of your code
and then you need to update the selectedRow variables
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Uncheck the previous checked row
selectedRowIndexPrevious = selectedRowIndex
// **UPDATED** need to set the selectedRowIndex
selectedRowIndex = indexPath.row
// **UPDATED**
// reload needs an array of indexPath
// so we can supply the previous selection AND the current one
NSIndexPath* rowToReloadPrevious = [NSIndexPath indexPathForRow: selectedRowIndexPrevious inSection:0];
NSIndexPath* rowToReloadNew = [NSIndexPath indexPathForRow: selectedRowIndex inSection:0];
NSArray* rowsToReload = [NSArray arrayWithObjects:rowToReloadPrevious, rowToReloadNew, nil];
[tableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationNone];
}
within the cellForRowAtIndexPath, you just need to look at selectedRowIndex instead of checking the text
if (indexPath.row == selectedRowIndex) {
cell.textLabel.textColor = [UIColor whiteColor];
} else {
cell.textLabel.textColor = [UIColor grey1Color];
}
}

ios7 UITableViewCell selectionStyle won't go back to blue

Xcode 5.0, iOS 7 and updating an existing app. UITableView selected row is now gray, not blue.
From what I've read they changed the default selectionStyle to gray. But "Blue" is still an option in IB and UITableViewCellSelectionStyleBlue still exists. Checking out the new HIG, it doesn't look like they removed the blue and the "Settings" app still using blue cell selection.
I've tried setting the value in IB and in code, but no luck. Any ideas on what I need to do to get the blue selection style back?
There is only one selectionStyle in iOS7, to change you need to do this manually like below:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
....
UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = [UIColor colorWithRed:(76.0/255.0) green:(161.0/255.0) blue:(255.0/255.0) alpha:1.0]; // perfect color suggested by #mohamadHafez
bgColorView.layer.masksToBounds = YES;
cell.selectedBackgroundView = bgColorView;
....
return cell;
}
I know this has already been answered but the last thing I wanted to do was touch all of my cellForRowAtIndexPath methods. So, I used an appearance proxy in my App Delegate. I took #null's code above to set the selected background view and in the applicationDidFinishLaunching:withOptions: method I placed this code.
UIView *bgColorView = [[UIView alloc] init];
//the rest of null's code to make the view
[[UITableViewCell appearance] setSelectedBackgroundView:bgColorView];
Then to make the white text hi light:
[[UILabel appearanceWhenContainedIn:[UITableViewCell class], nil] setHighlightedTextColor:[UIColor whiteColor]];
This made a global change in my app. The appearance proxy was introduced in iOS5 and Mattt has a great article on how to use it at his NSHipster blog.
Probably it could help you. I have my custom cell and to make it selected with needed color I have overwrite setHighlighted and setSelected now it's look like that
#define IOS_7 (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1 ? YES : NO)
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
[self changeSelectionColorForSelectedORHiglightedState:selected];
// Configure the view for the selected state
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
[super setHighlighted:highlighted animated:animated];
[self changeSelectionColorForSelectedORHiglightedState:highlighted];
}
- (void)changeSelectionColorForSelectedORHiglightedState:(BOOL)state
{
if (IOS_7) {
if (state) {
self.contentView.backgroundColor = [UIColor blueColor];
}
}
}
I know I'm really late to the party, but I'll offer my IOS10 work around as well. Don't touch any of your other code, but add:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.backgroundColor = [UIColor blueColor];
cell.textLabel.textColor = [UIColor whiteColor];
... whatever else you do ...
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
cell.textLabel.textColor = [UIColor blackColor];
}

placeholder for empty uitableview section

After lots of searching, I can't seem to find what I'm looking for.
I have a UITableview where some of the sections may be blank to begin with. Here's a picture to help get an idea of what I'm talking about. I want to have some TEXT (not a table cell) in the middle between the footer and the header. Is there anything that I may have overlooked?
What I did was create a UILabel with the same size as the tableview and add it to the tableview, something like:
UILabel* emptyLabel = [[UILabel alloc] init];
emptyLabel.textAlignment = UITextAlignmentCenter;
emptyLabel.backgroundColor = [UIColor clearColor];
emptyLabel.frame = self.tableView.bounds;
emptyLabel.text = #"Empty";
[self.tableView addSubview:emptyLabel];
You can then use the hidden property to show it or hide it, e.g. emptyLabel.hidden = TRUE;
Because of the nature of UITableViews, I'm not sure you could achieve replacing the UITableCell view with something else. However there's no reason you can't completely alter the table cell itself to look like a plain UITextLabel and not a cell! You could do something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
/* Initial setup here... */
if (thisCellHasNoDataYet) {
// Prevent highlight on tap
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor blackColor];
cell.textLabel.text = #"TEXT YOU WANT THE 'CELL' TO DISPLAY";
// etc...
}
else {
// Otherwise we have data to display, set normal cell mode
[cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
cell.backgroundColor = [UIColor whiteColor];
// etc...
}
The benefit here is that once your condition is met, you just have to set the boolean (I used thisCellHasNoDataYet) to TRUE and call reloadData on your table!

Clear answer on how to Mask a UIView as a UITableViewCell selectedBackgroundView

I've read and tried a few answers I have found on StackOverflow. I've also read and tried a few things from blogs, but nothing seems to accomplish what I am looking for.
I create a UIView and set it's background color to my desired UITableViewCell selection color (instead of the standard blue or gray selection colors). I add this UIView to my cell's selectedBackgroundView and this works fine, my cell changes to the desired color on user selection.
This method works great on Plain UITableViews; not so well on Grouped. On a grouped UITableView, the 1st and last cell do not conform to clip / mask bounds as demonstrated in the below screenshots.
I know there is no way to round just the top-left and top-right corners only.
I want to do this strictly by code, without images.
Question
Does anyone know of a nice little work around to change the selectedBackgroundView color of a UITableViewCell using only the UIView and not images AND to make the 1st and last cell conform to the rounded corner boundaries?
Example
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * CellIdentifier = #"Cell";
WCSBadgedCell * cell = [[WCSBadgedCell alloc] initWithStyle:UITableViewCellStyleSubtitle andBadgeStyle:0 reuseIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[WCSBadgedCell alloc] initWithStyle:UITableViewCellStyleDefault andBadgeStyle:0 reuseIdentifier:CellIdentifier];
}
UIView *bgColorView = [[UIView alloc] init];
[bgColorView setBackgroundColor:DARKBROWN];
[bgColorView setClipsToBounds: YES];
[cell.layer setMasksToBounds:YES];
[cell setSelectedBackgroundView:bgColorView];
[cell.textLabel setText: #"Testing a Cell"];
return cell;
}
Screenshots
Solution
I Accepted CodaFis answer because he added a comment which pointed to a pretty nice (yet lengthy) solution. I had to do quite a bit of revamping, but in the end, I now have the selectedBackgroundView's I needed which round the corners on the 1st and last cells, thanks again!
Here is a n example of how I achieved this.
I assume that you are using a UITableViewCell subclass because of the complexity of your cell. This is how I've been doing it:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]))
{
self.clipsToBounds = YES;
UIView* bgView = [[UIView alloc] init];
bgView.backgroundColor = [UIColor colorWithWhite:0.f alpha:0.25f];
self.selectedBackgroundView = bgView;
//other code
}
return self;
}
This produces a sort of dark grey overlay on the cell, not images required!
In your case, the exact color of your selected cell (thanks to the handy dandy Digital Color Meter) would be
[UIColor colorWithRed:106.0f/255.0f green:51.0f/255.0f blue:6.0f/255.0f alpha:1.0f];
and the white text would be
- (void)setSelected:(BOOL)sel animated:(BOOL)animated
{
[super setSelected:sel animated:animated];
if (sel)
{
self.textLabel.textColor = [UIColor whiteColor];
}
else
{
self.textLabel.textColor = [UIColor colorWithRed:(105.f/255.f) green:(50.f/255.f) blue:(6.f/255.f) alpha:1.f];
}
}
I had the same problem, and fixed it by overriding -(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated in my UITableViewCell subclass and setting no selection style when creating the cell
//set no selection style in the cell
...
[self setSelectionStyle:UITableViewCellSelectionStyleNone];
...
//override setHighlighted to manually set the regular/highlighted background colors
-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
if(highlighted){
self.backgroundColor = [UIColor greenColor];
}
else {
self.backgroundColor = [UIColor redColor];
}
}

BackgroundColor of UITableViewCellStyleSubtitle labels?

I am trying to create a table with an image as a background.
To achieve this, I started out with the background:
self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];
This resulted in a background image which appears in tablecells as well. That is not something I want, so I tried to set the cell's backgroundColor:
cell.backgroundColor = [UIColor whiteColor];
This had no effect at all !!!. Hmmm strange.
So I tried this:
UIView *backgroundView = [[UIView alloc] init];
backgroundView.backgroundColor = [UIColor whiteColor];
cell.backgroundView = backgroundView;
[backgroundView release];
This works almost. The only problem left is that the textLabel & the detailTextLabel still show the background behind them.
Setting the backgroundColor on those labels to white doesn't do anything either.
How do I proceed? Where do I go wrong? I am trying to achieve a tableView like the worldClock app has.
To change the background colour of the table view cell, you'll need to set it in tableView:willDisplayCell:forRowAtIndexPath: rather than tableView:cellForRowAtIndexPath:
otherwise it won't have any effect, for example:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.backgroundColor = [UIColor whiteColor];
}

Resources