I have UITableView in which i want to add Background image on first cell in viewDidLoad method, after adding image on first cell, when user selects any other row i want to hide my background image.
Is it possible to do ?
Please help and thanks in advance.
Edit:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath{
if(indexPath.row==0){
cell.backgroundView = [ [UIImageView alloc] initWithImage:[[UIImage imageNamed:#"active-tab.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0] ];
flag=true;
NSLog(#"willDisplayCell");
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (flag==true) {
cell.backgroundView = nil; //How to get `cell` here ?
//How to remove BGImage from first cell ???
}
}
Take a look at this question and the second answer gives a great description.
In short you should not be using the viewDiLoad callback but instead the
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { ... }
From here you can customise each cell's background as you wish, just reload the row when the user clicks.
How to customize the background color of a UITableViewCell?
EDIT
Now because you added your code I can clearly see the problem:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"BTSTicketsCellIdentifier";
CRHomeCategCell *cell = (CRHomeCategCell *)[_tblCateg dequeueReusableCellWithIdentifier:CellIdentifier];
cell.backgroundView = nil;
}
This does not do what you think it does. dequeueReusableCellWithIdentifier:CellIdentifier gives you a NEW instance of a cell based off the one identified by the identifier.
You are not getting a reference to the row here, you are creating a new row and settings its background to nil.
Your code should be something more like this:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath{
if(indexPath.row==0){
if(cell.backgroundView == nil)
{
cell.backgroundView = [ [UIImageView alloc] initWithImage:[ [UIImage imageNamed:#"active-tab.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0] ];
NSLog(#"willDisplayCell");
}
else
{
cell.backgroundView = nil;
NSLog(#"willHideCell");
}
}
}
This is not a great solution, I personally would do something more like having this custom cell hold a boolean and switch its state and check that. But this is up to you to develop, this is the general idea of how it should work.
EDIT 2:
Since you are determined to run it inside didSelectRowAtIndexPath and also completely incapable of doing any level of research or putting any effort into your work might I suggest the method:
tableView cellForRowAtIndexPath:<#(NSIndexPath *)#>
it works add table view delegates in your class
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath
*)indexPath
{
if((indexPath.row)==0) {
cell.backgroundView = [ [UIImageView alloc] initWithImage:[ [UIImage imageNamed:#"normal.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0] ];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
yourcustomcell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.backgroundView = [ [UIImageView alloc] initWithImage:[ [UIImage imageNamed:#"pressed.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0] ];
or
cell.backgroundView = nil;
[tableview reloadData];
}
Related
Issue: I only want to show the selected cells with checkmark. I don't want the grey highlight.
I tried:
cell.selectionStyle = UITableViewCellSelectionStyleNone
but didn't work.
Here is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
ProfileSelection *profile = [self.profileSelections objectAtIndex:indexPath.row];
cell.textLabel.text = [profile profileName];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.profileSelectionsTableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
ProfileSelection *profile = [self.profileSelections objectAtIndex:indexPath.row];
self.mobileProfileId = [profile.profileId stringValue];
[_continueButton setEnabled:YES];
}
How about this:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
The selectionStyle property should be enough to remove the highlight.
If you want to show the checkmark after the used has selected the row, you need to implement the tableView:didSelectRowAtIndexPath: method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tableView cellForRowAtIndexPath:visibleIndexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
In Swift, the easiest way is to deselect a cell without animation right after it has been selected:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: false)
}
delete your this function
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Try to use this your problem will be solved
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone
cell.textLabel.text = #"Checking Table View";
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Go to Storyboard. Select your Table View Cell. Set Selection to None. Then add below codes:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}
This thread looks a bit old, but I actually came across a decent solution for this recently. In case anyone stumbles across this thread, I figure I might as well post an answer. Especially since I spent hours trying to track this down.
I can't find my original sources anymore, but here's what I found out:
The highlight is made by a background view on the UITableViewCell on the selectedBackgroundView property. If we have a subclass of the table cell, we can detect the transition to the editing state with willTransitionToState: and set the background view to one that is clear/white instead of the blue/gray styles.
Here's what I ended up doing, and it works pretty well.
- (void)willTransitionToState:(UITableViewCellStateMask)state {
[super willTransitionToState:state];
// To remove the blue/gray highlight on the table cell when selected,
// set the selection background to a clear view.
if (state & UITableViewCellStateShowingEditControlMask) {
// If we're moving to an edit state, set the custom background view.
UIView *bgView = [[UIView alloc] init];
[bgView setTintColor:[UIColor whiteColor]];
[bgView setBackgroundColor:[UIColor clearColor]];
[self setSelectedBackgroundView:bgView];
} else {
// Otherwise, just remove it completely.
// The system should handle the rest.
[self setSelectedBackgroundView:nil];
}
}
The plus side to this over the other solutions I've seen is that this one is quite minimal. No need for tracking instance variables or anything else.
I have a custoum cell with an image , and i want to change the image only when cell is selected.
This i was trying :
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (!tableView.tag==0) {
TableViewCell2 *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (!cell) {
cell=[[TableViewCell2 alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
// cell.cam.image = [UIImage imageNamed:#"cam_normal.png"];
cell.cam.highlightedImage = [UIImage imageNamed:#"cam_selected.png"];
}
}
but the image is not changing.
This is working for a normal cell.
Another try was this in cellForRowAtIndexPath
if (cell.selected==TRUE) {
cell.cam.image=[UIImage imageNamed:#"cam_selected.png"];
}
You already get the cell as a parameter but fetch another one when using dequeueReusableCellWithIdentifier!
Try something like this:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!tableView.tag==0)
{
TableViewCell2 *changeImageCell = (TableViewCell2*) cell;
changeImageCell.cam.highlightedImage = [UIImage imageNamed:#"cam_selected.png"];
}
}
You have to do 2 things:
1. Change the image immediately when the cell is selected.
To do this you must first implement UITableViewCell delegate. But since you already have tableViewWillDisplayCel:forRowAtIndexPath:, I assume that you already have the delegate implemented.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
TableViewCell2 *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.cam.highlightedImage = [UIImage imageNamed:#"cam_selected"];
}
You could change the image back when the user deselect the cell.
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
TableViewCell2 *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.cam.highlightedImage = [UIImage imageNamed:#"cam_unselected"];
}
2. Persist the selection when the cell is reused.
Again, when the cell is reused, you have to check whether it is selected or not. Then assign the image accordingly.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TableViewCell2 *cell = [tableView dequeReusableCellWithIdentifier:#"cell"];
BOOL isRowSelected = [indexPath isEqaul:[tableView indexPathForSelectedRow]];
if (isRowSelected) {
cell.cam.highlightedImage = [UIImage imageNamed:#"cam_selected"];
} else {
cell.cam.hightlightedImage = [UIImage imageNamed:#"cam_unselected"];
}
}
Two things I notice here. First you never use true or TRUE in Objective-C. You use BOOL with YES and NO. Second, you rarely need to use dequeReusableCellWithIdentifier: outside tableView:cellForRowAtIndexPath:. Why did you do it there?
This question already has answers here:
Changing background color of selected cell?
(30 answers)
Closed 8 years ago.
I am making an app in which I am showing my data in a UITableView. I am stuck. I want to change the colour of the selected cell. How to do this?
Below is my code in -didSelectRowAtIndexPath
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"the messageid==%#",[[self.inboxmessagesarray objectAtIndex:indexPath.row ] objectForKey:#"messageId"]);
manage.messageid=[[self.inboxmessagesarray objectAtIndex:indexPath.row ] objectForKey:#"messageId"]; // here i pass the value to singleton class
[self performSegueWithIdentifier:#"segueIdentifier" sender:tableView];
}
Update your code as mentioned below:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"the messageid==%#",[[self.inboxmessagesarray objectAtIndex:indexPath.row ] objectForKey:#"messageId"]);
manage.messageid = [[self.inboxmessagesarray objectAtIndex:indexPath.row ] objectForKey:#"messageId"]; // here i pass the value to singleton class
[self performSegueWithIdentifier:#"segueIdentifier" sender:tableView];
// Add this line to set selected default gray style
cell.selectionStyle = UITableViewCellSelectionStyleGray;
}
Use selectionStyle property to get cell highlighed. For more details refer UITableViewCellSelectionStyle
May be this will be useful to u...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIView *selectedRowColor = [[UIView alloc] init];
selectedRowColor.backgroundColor = [UIColor redColor];
cell.selectedBackgroundView = selectedRowColor;
}
in your cellForRowAtIndexPath has two options for selection only Blue and another one is Gray
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) indexPath
{
/// here your cell identifier name and details
UIView *changeselectionColor = [[UIView alloc] init];
changeselectionColor.backgroundColor = [UIColor colorWithRed:(245.0/255.0) green:(245.0/255.0) blue:(245.0/255.0) alpha:1]; // change the RGB as you like
cell.selectedBackgroundView = changeselectionColor;
//...... here add your cell details.. //
}
or in another choice no 2 call this method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIView * changeselectionColor = [[UIView alloc] init];
changeselectionColor.backgroundColor = [UIColor GreenColor];
cell.selectedBackgroundView = changeselectionColor;
}
For some reason my UITableView Delegate method didSelectRowAtIndexPath is not getting called until after I select the row. Also, although I set the editing style of my UITableView to UITableViewCellEditingStyleDelete, when I swipe my finger across the tableview it doesn't show the delete button. I have set the delegate and datasource properties of my tableview in storyboard to my viewcontroller, but the delegate methods still aren't getting called properly. The cells still function and will navigate to my other detailview, but I'm just getting some very weird behavior. Here's the code I'm using for my tableview:
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_lists count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 44;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"MasterListCell";
/* Set up list cell */
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
CGRect myImageRect = CGRectMake(0.0f, 0.0f, 15.0f, 15.0f);
UIImageView *myImage = [[UIImageView alloc] initWithFrame:myImageRect];
[myImage setImage:[UIImage imageNamed:#"cell-arrow.png"]];
cell.accessoryView = myImage; //cellArrowNotScaled;
cell.editingAccessoryType = UITableViewCellEditingStyleDelete;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
/* Define a new List */
List *list = [_lists objectAtIndex:indexPath.row];
// cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.font = [UIFont fontWithName:#"Roboto-Medium" size:15];
cell.textLabel.text = list.name;
cell.textLabel.highlightedTextColor = [UIColor blackColor];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:
(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//add code here for when you hit delete
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Are you sure?" message:#"This list will be permanently deleted." delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK",nil];
[alert show];
}
}
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *currentSelectedIndexPath = [tableView indexPathForSelectedRow];
if (currentSelectedIndexPath != nil)
{
[[tableView cellForRowAtIndexPath:currentSelectedIndexPath] setBackgroundColor:[UIColor yellowColor]];
}
return indexPath;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"did select row");
[[tableView cellForRowAtIndexPath:indexPath] setBackgroundColor:[UIColor yellowColor]];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (cell.isSelected == YES)
{
[cell setBackgroundColor:[UIColor yellowColor]];
}
else
{
[cell setBackgroundColor:[UIColor whiteColor]];
}
}
Update answer
From your comment below, I see what you're getting at. You're trying to fake a custom selected background for grouped style (which can't be customized without providing custom images) by turing of selection highlighting and instead setting the unselected background color when the cell is tapped. You can do this in shouldHighlightRowAtIndexPath:
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.backgroundColor = [UIColor greenColor];
return YES;
}
This method gets called before didSelectRowAtIndexPath even when selection style is none. You'll need to elaborate on the above solution to set the color back when the cell is supposed to be unhighlighted.
Original answer
didSelectRowAtIndexPath is not getting called until after I select the row
That is by design, hence the past tense "did" in the name.
Also, although I set the editing style of my UITableView to UITableViewCellEditingStyleDelete, when I swipe my finger across the tableview it doesn't show the delete button.
You've got to implement the data source method tableView:commitEditingStyle:forRowAtIndexPath: to have the delete button appear. If you think about it it makes sense. You haven't provided a way for your data source to respond to the edit, so iOS concludes that it shouldn't edit.
I'm saying that when I press down on a cell with UITableViewSelectionStyleBlue it shows up blue. However, when I set it to none and attempt to change the background color in didSelectRowAtIndexPath it doesn't change until after I have lifted my finger up off the cell. I want the background color of the cell to change when I put my finger down without lifting it
What are you ultimately trying to accomplish? It sounds like you want to do a custom highlight color. The way to do that is to replace the cell's selectedBackgroundView with your own view and set that view's background color:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//...
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.bounds];
cell.selectedBackgroundView.backgroundColor = [UIColor greenColor];
//...
}
If that's not what you're going for, please clarify and I'll update my answer.
I want to implement touch up and touch down like functionality for my TableView Cell.
My need is giving different background color to the cell.
Give different background when we touch down the cell and different color when we touch up.
I try it with following way :
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
[cell setBackgroundColor:[UIColor redColor]];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[cell setBackgroundColor:[UIColor greenColor]];
}
but the issue is didHighlightRowAtIndexPath is only available for iOS 6.0 not below that.
Is there another way to implement it.
In cellForRowAtIndexPath write below code:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CustomCellIdentifier = #"yourcell";
SettingsCell *cell = (SettingsCell *)[tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];
if (cell == nil) {
NSArray *nib = nib = [[NSBundle mainBundle] loadNibNamed:#"yourcell" owner:self options:nil];
for(id oneObject in nib) {
if([oneObject isKindOfClass:[yourCell class]]) {
cell = (yourCell *)oneObject;
}
}
//to change background color of selected cell
UIView *backgroundView = [[UIView alloc] init];
backgroundView.backgroundColor = [UIColor blueColor];
cell.selectedBackgroundView = backgroundView;
}
return cell;
}
And on didselectRow at indexPath, change to another color
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView reloadData];
UITableViewCell *cell=(UITableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundColor:[UIColor redColor]];
}
Try this, you can have two images for selected and unselected rows.
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"unselected.png"] ];
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"selected.png"] ];
You will be adding this in cellForRowAtIndexPath method. You can take state from didSelect right?? Trust me i have tried almost 10 different ways to do this and only this solution worked fine in all cases perfectly.