UITableView: Show selected cell background only when in edit mode - ios

When my tableView is not in edit mode, I don't want a user to be able to touch the cells and have them highlight. But, because I have set allowsSelectionDuringEditing to YES, users can select cells when in editing mode.
How do I only show the cell highlighted view or color ONLY when in editing mode?

Interesting scenario, luckily it's as simple as this:
// -tableView:shouldHighlightRowAtIndexPath: is called when a touch comes down on a row.
// Returning NO to that message halts the selection process and does not cause the currently selected row to lose its selected look while the touch is down.
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath{
return self.isEditing;
}
As you can see from Apple's comment shouldHighlight is the first step in the selection process, so that is the place to halt it in the case of table being edited.

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier=#"Cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
//YOUR inits
}
if(self.editing){
[cell setSelectionStyle:UITableViewCellEditingStyleNone];
}else
[cell setSelectionStyle:UITableViewCellEditingStyleBlue];
return cell;
}
and
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if(self.editing)return; //NO ACTION
}

I figured it out. Here is my method that sets tableView editing mode:
- (void)tableViewEdit {
if (self.tableView.editing) {
[self.editButton setTitle:NSLocalizedString(#"Edit", nil) forState:UIControlStateNormal];
self.tableView.allowsSelection = NO;
} else {
[self.editButton setTitle:NSLocalizedString(#"Done", nil) forState:UIControlStateNormal];
self.tableView.allowsSelection = YES;
}
[self.tableView setEditing:!self.tableView.editing animated:YES];
}//end
I also previously set self.tableView.allowsSelection to NO as a default, so it will only be YES after editing mode is entered.

Related

iOS check table cell Button while user Select or Deselect cell

Actually I am creating collection of entries using User input. where i want to used Check Box for selection and diselection. instead of checkbox i have used Button where when user select on cell Button image get changed, but when one select again on that cell Nothing Happen. I have tried this.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if([[cell.btn backgroundImageForState:UIControlStateNormal]isEqual:[UIImage imageNamed:#"unchecked.png"]])
{
[cell.btn setBackgroundImage:[UIImage imageNamed:#"checked.png"] forState:UIControlStateNormal];
}
And in didDeselectRowAtIndexPath
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
if([[cell.btn backgroundImageForState:UIControlStateNormal]isEqual:[UIImage imageNamed:#"checked.png"]])
{
[cell.btn setBackgroundImage:[UIImage imageNamed:#"unchecked.png"] forState:UIControlStateNormal];
}
}
Please Help me out where i am stucking.
You must be using data object whose data is used to show in table view just add one property in it isSelected . Lets name the array as "data".
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[data objectAtIndex:[indexPath row]].isSelected=YES;
[tableView reloadData];//or just row
}
And in didDeselectRowAtIndexPath
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[data objectAtIndex:[indexPath row]].isSelected=NO;
[tableView reloadData];//or just row
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//initial code
//addd this code
if([data objectAtIndex:[indexPath row]].isSelected){
//set checked image
}else {
//set unchecked image
}
}
you have to set property of cell
when you select the cell.
cell.selected = YES;
and when you deselect the cell then
cell.selected = NO;
if your tableview reload than you have to do this in cellForRowAtIndexPath Method
because when you reload the table than you have to remember the cell selection state.
In your code there is never called tableView didDeselect method
didDeselect only called when your tapped cell is selected.
Hope this will helps you

Table cell borders get visible when selecting a cell in UITableView in IOS

I have implement a side out menu for my currently developing ios application.There I used a UITableViewController as my menu and I want to highlight the menu item selected. I have done the highlighting thing and the problem is when I select one of those menu items, up and down borders of the table cell get visible.
This is my side menu and look at the selected table cell(menu item). there are up and down cell borders or something like that.
This is my code that I used to highlight the selected cell
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
[self setCellColor:[UIColor colorWithRed:0.192 green:0.192 blue:0.192 alpha:1] ForCell:cell]; //highlight colour
}
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
[self setCellColor:[UIColor colorWithRed:0.239 green:0.239 blue:0.239 alpha:1] ForCell:cell]; //normal color
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
[self setCellColor:[UIColor colorWithRed:0.192 green:0.192 blue:0.192 alpha:1] ForCell:cell];
}
- (void)setCellColor:(UIColor *)color ForCell:(UITableViewCell *)cell {
cell.contentView.backgroundColor = color;
cell.backgroundColor = color;
//cell.backgroundView.backgroundColor = color;
}
I already tried to change the selected cell border color in different different ways but all those were not successful.
Can someone please help me to get this solved.
try this.
Select tableview and go to Attribute Inspector.
In separator just set the table view separator color to clear color.
You just need to set the "selection" property of UITableViewCell to "none" and add the following code to your controller. see screenshot its working.
Code:
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
[self setCellColor:[UIColor colorWithRed:0.239 green:0.239 blue:0.239 alpha:1] ForCell:cell]; //normal color
}
Try this.
Select tableview and go to Attribute Inspector.
Find the property Separator and make it Default to None.
And also set the color to Clear Color.
I hope it will work for you...good luck !! :)

How to make auto deselecting tableview cell

I have a table view
and when I click the cell everything is fine
however, when I remove my fingers from the phone, the cell stays selected
how can I make it become deselected when the user stops touching the given cell and does not touch another cell
Simple :
In this method : didSelectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UIActionSheet *photoPicker ;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
you have to set the style in cellForRowAtIndexPath or change the cell in willSelectRowAtIndexPath and change back in didSelectRowAtIndexPath.
For example
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// ...
cell.selectionStyle = UITableViewCellSelectionStyleBlue; // or an other style
// ...
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// ...
[tableView deselectRowAtIndexPath:indexPath animated:NO];
// ...
}
Put the following in the UITableView delegate.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setSelected:NO animated:YES];
}
Have you considered to handle the touch events?
For example: Add a UITapGestureRecognizer, detect which cell is being touched by using the -(CGPoint)locationInView:(UIView *)view method. Mark the cell as selected when the touch begins and mark as deselected when the touch ends.
Have you assigned delegate to UITableView?
self.tableView.delegate = self;
That is the reason why you experience this
this does not work - the cell does not show indication of being
selected
In tableView:didSelectRowAtIndexPath:, set the selected property of the cell to NO using the method setSelected:animated:.
E.g.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setSelected:NO animated:YES];
}
NOTE:
Setting the cell's selected property = NO and animated = YES with the above method will cause the separator to disappear. The only way I've found to circumvent this is to set animated = NO but, if I find another way I will update my answer.

How to I make check marks appear and disappear when I click multiple rows?

I want a table which, when you click different rows, they gain or lose a checkmark to show they are either selected or not selected.
Currently my tableview will let me select and deselect different rows. But a checkmark will only appear once I have clicked one and then another. The same happens when I deselect, I click a row with a checkmark then click another row and the checkmark disappears.
Here is my code currently:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * exerciseChoiceSimpleTableIdentifier = #"ExerciseChoiceSimpleTableIdentifier";
UITableViewCell * exerciseChoiceCell = [tableView dequeueReusableCellWithIdentifier:exerciseChoiceSimpleTableIdentifier];
if (exerciseChoiceCell == nil) {
exerciseChoiceCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:exerciseChoiceSimpleTableIdentifier];
}
//Here we get each exercise we want to display
BExercise * exercise = [[_data getExerciseCompleteList] objectAtIndex:indexPath.row];
//Name the cell after the exercises we want to display
exerciseChoiceCell.textLabel.text = exercise.name;
return exerciseChoiceCell;
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
if ([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryNone)
{
// Uncheck the row
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
// Check the row
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}
}
I think the problem is to do with it being selected rather than touch up inside and deselecting when the finger is released from the button.
I am expecting the answer to be quite straight forward but all the similar questions on stackflow haven't dealt with the checkmarks delayed appearance.
It would be great to understand the root of this problem and how to fix it.
change the method
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
by
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

UITableView didselectrowatindexpath not getting called

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.

Resources