I have a custom UITableViewCell named as Hobbies.
Everything is working fine.Except one UIIssue.
When user taps on any cell I want to change the text colour of that particular Cell .And when user select another I want the previous selected cell should return to its original state.
Currently I am able to change the colour on Cell select but not able to revert it back when user selects another.
Here is the code I am using to change the textColor of a particular cell:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
HobbiesCell *cell = (HobbiesCell*)[tableView cellForRowAtIndexPath:indexPath];
cell.dateLabel.textColor = [UIColor colorWithWhite:255 alpha:0.5f];
}
How can I revert It back when user selects another cell.
You can create an object of UITableViewCell say previousCell and assign it each time you select one. This will be your last selected cell and you can assign it the default color each time you click a new cell.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
HobbiesCell *cell = (HobbiesCell*)[tableView cellForRowAtIndexPath:indexPath];
previousCell.dateLabel.textColor = [UIColor blackColor]; //Assuming that this is the color you want to go back
cell.dateLabel.textColor = [UIColor colorWithWhite:255 alpha:0.5f];
previousCell = cell;
}
declare this variable
int selectedIndex;
in your cellForRowAtIndexPath
if(indexPath.row == selectedIndex)
{
cell.dateLabel.textColor = [UIColor colorWithWhite:255 alpha:0.5f];
}
else
{
cell.dateLabel.textColor = [UIColor colorWithWhite:0 alpha:0.5f];//your default cell color
}
and in your didSelectRowAtIndex
selectedIndex = indexPath.row;
[tableView reloadData];
You should always keep in mind that the cells are reusable, so the one you change will be used as is for displaying other rows when you scroll.
Instead, you should keep an array of your own models that keep the data (in your case color information) and use the cells only for displaying it.
To revert the color simply keep a reference to the latest NSIndexPath.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MyRowModel *prevRowModel = [self.rowModels objectAtIndex:self.lastIndexPath.row];
prevRowModel.color = [UIColor colorWithWhite:255 alpha:1f];
MyRowModel *rowModel = [self.rowModels objectAtIndex:indexPath.row];
rowModel.color = [UIColor colorWithWhite:255 alpha:0.5f];
[self.tableView reloadRowsAtIndexPaths:#[indexPath, self.lastIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
self.lastIndexPath = indexPath;
}
If you go for reload the tableview then try this .
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// reload the table
[tableView reloadData];
HobbiesCell *cell = (HobbiesCell*)[tableView cellForRowAtIndexPath:indexPath];
previousCell.dateLabel.textColor = [UIColor colorWithWhite:255 alpha:0.5f]; // color insert which you want to insert
}
hope it helps you without adding varible.
Try cell.textLabel.highlightedTextColor.
if (cell == nil) {
........
/* your cell initiation code */
........
cell.textLabel.textColor = [UIColor whiteColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.highlightedTextColor = [UIColor orangeColor];
}
You need to maintain a reference to the currently selected indexPath. Something like...
#property (nonatomic, strong) NSIndexPath *currentHobby;
Then in your didSelectRowAtIndexPath: method insert this...
if(_currentHobby && ![_currentHobby isEqual:indexPath]) {
HobbiesCell *currentCell = [tableView cellForRowAtIndexPath:_currentHobby];
currentCell.dateLabel.textColor = [UIColor originalColor];
}
_currentHobby = indexPath;
Then in your cellForRowAtIndexPath: make sure you include...
if([indexPath isEqual:_currentHobby]) {
cell.dateLabel.textColor = [UIColor selectedColor];
} else {
cell.dateLabel.textColor = [UIColor originalColor];
}
Related
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];
}
}
I have a tableview and the tableview is filled with items from a .plist.
I then use this method to add functionality to when something is pressed:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == 0) { //do something
}
if (indexPath.row == 1) { //do something
}
So on and so forth
I've set a font color with in IB / The storyboard however I'd like to change the color of the text when it's being pressed. So basically I want it to act like a UIButton when it's pressed.
And of course not all text should be change when one cell is pressed, only the color of the text in the current cell that is being pressed.
you could change everything in the selected cell
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.font=[UIFont fontWithName:#"Arial"];
cell.contentView.backgroundColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0];
}
-(void)tableView:(UITableView *)tableView deSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.font=[UIFont fontWithName:#"Arial"];
cell.contentView.backgroundColor = //default color;
}
UIView *selectedBackgroundView = [[UIView alloc] init];
selectedBackgroundView.backgroundColor = [UIColor redColor];
cell.selectedBackgroundView = selectedBackgroundView;
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (indexPath.row == 0)
{
cell.labelText.color = [UIColor redColor];
}
if (indexPath.row == 1)
{
cell.labelText.color = [UIColor greenColor];
}
}
One option (I assume you have a UITableViewCell subclass MyTableViewCell, adjust as needed):
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == 0) { //do something
}
if (indexPath.row == 1) { //do something
}
MyTableViewCell *cell = (MyTableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
// Adjust your cell contents as needed
Also add deselection delegate method to revert changes:
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
MyTableViewCell *cell = (MyTableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
// Adjust your cell contents back to normal
Another option would be to override setSelected:animated: and setHighlighted:animated in your UITableViewCell subclass and make appropriate changes to cell elements there.
I have a UIButton inside a UITableViewCell. When the app is first launched, it works as expected, where I created it's frame.
When I scroll pass the cell which holds the button, it creates a second instance of the button slightly below the button.
Here's a video to illustrate my problem: http://pixori.al/DJ1k
Here's the code for the UITableViewCell and also how I populate the cells.
Not sure why it's behaving like this.
#pragma mark - UITableViewDataSource
// 3 sections, (1 = mistarOverview) (2 = hourlyForecast) (3 = dailyForecast)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
return MAX(6,6) + 1; //TODO add getNumberOfClasses for people with 7 or 8 classes
} else if (section == 1) {
return MIN([[MAManager sharedManager].hourlyForecast count], 6) + 1;
} else {
return MIN([[MAManager sharedManager].dailyForecast count], 6) + 1;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Redefine layout variables in method from `viewDidLoad`
CGFloat inset = 20; // For padding
if (! cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
// Sets up attributes of each cell
cell.selectionStyle = UITableViewCellSelectionStyleNone; //TODO none
cell.backgroundColor = [UIColor colorWithWhite:0 alpha:0.2];
cell.textLabel.textColor = [UIColor whiteColor];
cell.detailTextLabel.textColor = [UIColor whiteColor];
QBFlatButton* loginButton = nil;
if (indexPath.section == 0) {
if (indexPath.row == 0) {
[self configureHeaderCell:cell title:#"Grades"];
if ([cell.textLabel.text isEqual: #"Grades"] && (!loginButton) && (indexPath.row == 0) && (indexPath.section == 0)) {
UIView *cellView = cell.contentView;
CGRect loginButtonFrame = CGRectMake((cellView.frame.size.width - (80 + inset)), 18, 80, (cellView.frame.size.height));
loginButton = [[QBFlatButton alloc] initWithFrame:loginButtonFrame];
[loginButton addTarget:self action:#selector(loginButtonWasPressed)forControlEvents:UIControlEventTouchUpInside];
loginButton.faceColor = [UIColor grayColor];
loginButton.sideColor = [UIColor clearColor];
loginButton.radius = 6.0;
loginButton.margin = 4.0;
loginButton.depth = 3.0;
loginButton.alpha = 0.3;
loginButton.titleLabel.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:20];
[loginButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[loginButton setTitle:#"Login" forState:UIControlStateNormal];
[cellView addSubview:loginButton];
}
} else {
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
cell.textLabel.text = [NSString stringWithFormat:#"Period %ld A+", (long)indexPath.row];
cell.detailTextLabel.text = #"Class name";
//TODO get grades and config using method (TB Created)
}
} else if (indexPath.section == 1) {
if (indexPath.row == 0) {
[self configureHeaderCell:cell title:#"Hourly Forecast"];
}
else {
// Get hourly weather and configure using method
MACondition *weather = [MAManager sharedManager].hourlyForecast[indexPath.row - 1];
[self configureHourlyCell:cell weather:weather];
}
}
else if (indexPath.section == 2) {
if (indexPath.row == 0) {
[self configureHeaderCell:cell title:#"Daily Forecast"];
}
else if (indexPath.section == 2) {
// Get daily weather and configure using method
MACondition *weather = [MAManager sharedManager].dailyForecast[indexPath.row - 1];
[self configureDailyCell:cell weather:weather];
}
}
return cell;
}
Implement the following UITableView Delegate Method
-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
//In here, check the index path. When you have the cell that contains the button, pop it out from there by using [button removeFromSuperView];
}
Your problem occurs when you dequeue the cell. Since the cell is being reused, it already has the button and you're simply re-adding it again. This will solve your issue. However, I'd recommend you create a subclass for the UITableViewCell, and in it's prepareForReuse method, pop the button out. Up to you. Both will work.
Table view cells are not just deallocated then they move out of visible area. They are stored for reusing and then returned in tableView dequeueReusableCellWithIdentifier:CellIdentifier];
So you need to clean your cells after using or before reusing. There are several ways:
1.Add tag to your button when you create it
loginButton.tag = SOME_TAG;
just after
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
search for view with this tag
loginButton = [cell viewWithTag:SOME_TAG];
if loginButton != nil you can reuse it or remove from cell and then create a new one.
2.Implement UITableViewDelegate method
-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
and erase login button inside it.
3.Create custom UITableViewCellclass and implement prepareForReuse method.
You're adding the button every time you return a cell in this method. If you scroll the cell off the screen and back on, this method is called again for the same index path, and you will add the button again.
You declare the variable, do nothing with it, then check if it is nil. It will always be nil, so you always add the button.
A quick and dirty solution is to give the button a tag, then check for its existence using viewWithTag:.
A better solution is to make a custom cell subclass, and set one-time properties like this in the init method. Your cell contents seem very different for each section as well, so use different reuse identifiers for each section, and possibly a different cell subclass. Clearing out sub views is expensive and could hurt your scrolling performance.
When you run your project first time then cellForRowAtIndexPath is called.....
Then whenever you scroll tableView it again calls cellForRowAtIndexPath and reload data automatically..
So you have to take CellIdentifier as unique for each cell.
you have to remove static keyword from
static NSString *CellIdentifier = #"CellIdentifier";
now you have
NSString *CellIdentifier = #"CellIdentifier";
only this things
Now you have to write like below
NSString *CellIdentifier = [NSString stringWithFormat:#"%#",indexPath];
Now Enjoy.....
I want to change the color of a UITableView cell. I have this code but it doesn't work. Can someone explain to me why and what I should change?
[_myTableView cellForRowAtIndexPath : [NSIndexPath indexPathForItem:myIndexAsInt inSection:0]].contentView.backgroundColor = [UIColor greenColor];
To change the color of a standard UITableViewCell you need to do that by overriding the UITableViewDelegate method tableView:willDispayCell:forRowAtIndexPath: like so:
- (void)tableView:(UITableView *)tableView willDispayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.contentView.backgroundColor = color;
}
If your cell has custom content you might want to have a slightly different implementation.
to set the 3rd cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.row == 2)
{
cell.contentView.backgroundColor = [UIColor redColor];
}
return cell;
}
The line of code itself is ok syntacticaly.
Some things cannot be verified from my side. Please put a breakpoint on that line and run it.
0) By putting a breakpoint there, and seeing the system stop there, you actually check that that line is executed.
1) If step 0 was ok, check that you actually have an instance of table view (it must NOT be nil, maybe if you are using nibs, you forgot to create an IBoutlet).
2) Make sure the tableView has proper delegate and datasource. (usually the ViewController where those things you mention are handled...)
3) check that you are passing a proper type and proper value for the myIndexAsInt argument. It should be of NSInteger type and should be equal 2.
4) If all 3 above are ok, perhaps you are calling it from a wrong place.
Let us know how it went.
You can have an variable to hold the index position. So after your didSelectRowAtIndexPath delegate called just set the index position in that variable and reload the table. Use a condition in cellForRowAtIndexPath datasource method to check for index position and now set the background colour for that specific cell.
in .h file:
NSInteger indexPos;
in didSelectRowAtIndexPath delegate:
indexPos = indexPath.row;
in cellForRowAtIndexPath:
if (indexPath.row == indexPos) {
cell.backgroundColor = [UIColor colorWithRed:255/255.0f green:255/255.0f blue:255/255.0f alpha:1.0f];
} else {
cell.backgroundColor = [UIColor colorWithRed:0/255.0f green:0/255.0f blue:0/255.0f alpha:1.0f];
}
I have subclassed a UITableViewCell so that I can increase the scrolling performance which has worked out great for me so far.
In my subclass I have a method called seSelected that looks like this
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
if (selected) {
self.backgroundColor = [UIColor lightGrayColor];
}else{
self.backgroundColor = [UIColor whiteColor];
}
}
I would like to know how to make it so that if I touch the same cell it deselects the cell and changes the color back to white? I have tried a few different if statments in setSelected but nothings working.
Use this delegate method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
and call here method which manage selected and unselected cell.
One approach could be to set the tag on the cell and then use it to set the background color.
typedef enum {
CellSelected = 0,
CellDeselected
} CellSelection;
While creating the cell set the tag to "CellDeselected"
cell.tag = CellDeselected;
And then when cell is tapped just check which color you want to set in the background.
switch (customCell.tag) {
case CellSelected:
self.backgroundColor = [UIColor lightGrayColor];
break;
case CellDeselected:
self.backgroundColor = [UIColor whiteColor];
break;
default:
break;
}
customCell.tag = !customCell.tag;
Do like this...
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
str = [YourArray objectAtIndex:indexPath.row];//str is a string variable
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIndentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIndentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIndentifier];
}
cell.textLabel.text = [reminder objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor whiteColor];
if ([str isEqualToString:[reminder objectAtIndex:indexPath.row]])
{
cell.backgroundColor = [UIColor grayColor];
}
return cell;
}
You can use for this for your custom cell.....
use UITableViewCell method: [cell setSelectedBackgroundView:myBgColorView];.
Apple Documentation.
Example:
UIView *myBgColorView = [[UIView alloc] init];
myBgColorView.backgroundColor = [UIColor greenColor];
[cell setSelectedBackgroundView:myBgColorView];
set cell style:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
and your code will work. But, you set color only selected cell.
If you need set color when cell is pressed, override this method:
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated