iOS check table cell Button while user Select or Deselect cell - ios

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

Related

iOS UITableView : Set the correct cell as selected when tableview data changes

This is a little hard to explain, but I will try my best. The code below is just some simple code I put together to demonstrate my problem better. When a user selects the second cell (row) for example, the tableview properly changes the cell with this [cell selected:YES]; when tableview reloads. If the second cell is selected and my tableview reloads with more new cells, the wrong cell is selected. The previous selected second cell becomes the fourth or fifth cell when the tableview updates, but the second cell is still selected.
I know this is because of selectIndexPath index row is two. Is there a way around this?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
FriendCell *cell
if (selectedIndexPath.row == indexPath.row )
[cell selected:YES];
else
[cell selected:NO];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectIndexPath = indexPath;
}
If your source array can changed (add/remove elements) then you have to keep track of the selected item, not the selected index. You haven't shown what your data source object is, but let's say it was an array of strings:
#property (strong,nonatomic) NSMutableArray *tableData;
#property (strong,nonatomic) NSString *selectedItem;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
FriendCell *cell
if (self.selectedItem != nil && [self.tableData[indexPath.row] isEqualToString:self.selectedItem]) {
[cell selected:YES];
} else {
[cell selected:NO];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedItem = self.tableData[indexPath.row];
}

TableView deselectRowAtIndexPath does not call setHighlighted

I'm trying to change states of the label in my table view cell.
I want to keep a cell selected while I push a different view controller and move back to the view controller with my tableview.
When I select another row I want to remove highlight of previously selected row's lable (deselect the previously selected row) and Highlight the current row's label.
Is - (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated supposed to call - (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated with highlighted 'NO' for that Cell ?
Note: I'm not UITableViewController.
Keep cell selected:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.selected = YES;
//Other code
}
Ensure that the class cell don't have selected = NONE in interface builder.
Unselect last row:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *currentSelectedIndexPath = [tableView indexPathForSelectedRow];
if (currentSelectedIndexPath)
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.selected = NO;
}
return indexPath;
}
First, you should set TableviewCell properly [cell setSelectionStyle:UITableViewCellSelectionStyleGray]; in method :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Other then this, you can set custom background of selected cell by
UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = [UIColor colorWithWhite:0.97 alpha:1.0];
bgColorView.layer.masksToBounds = YES;
[cell setSelectedBackgroundView:bgColorView];
For Your highlight selected cell problem, you can use Simple flag like
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSIndexPath *ip= [NSIndexPath indexPathForRow:flagForLastSelectedRow inSection:0];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
flagForLastSelectedRow=indexPath.row;
}

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.

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.

UITableView: Show selected cell background only when in edit mode

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.

Resources