I want to use the Checkmark as an toggle switch to let user selects a bundle of items, but this is not working as expected - I have to tap the cell 2 times for the cell to toggle checkmark on/off. And if I do [tableView reloadData] instead of reloadRowsAtIndexPaths it does not work at all.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
} else if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
Your code is changing the view property and then reloading the table view from your model data. You should be changing the model data instead of the view property before you do the reload.
Related
This question already has answers here:
iOS UITableViewCellAccessoryCheckmark Visible ob every scroll
(4 answers)
Closed 6 years ago.
I've tried every single option available on this website for this problem but none of them seems to be working.
If I scroll down I see the checkmark. If I scroll back up the positioning of my selection is not the same.So as the problem is the same I wanted to open this question for one more time as a fresh start. Here is how I'm doing it:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
myTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (![selectedDX containsObject:myMutArray[indexPath.row]])
{
[selectedDX addObject:myMutArray[indexPath.row]];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
myTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ([selectedDX containsObject:myMutArray[indexPath.row]]) {
[selectedDX removeObject:myMutArray[indexPath.row]];
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
I've also tried it in in a single didSelectRowAtIndexPath method but the result is same.
Do you set the accessory type correctly when you return the cell in cellForRowAtIndexPath? It looks to me that you only set the accessory when the user taps on a cell but this is not enough.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
[...]
if ([selectedDX containsObject:myMutArray[indexPath.row]])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
[...]
}
Your cells are reused when you scroll in your table view. So one cell is reused for more than one of your items. This means the accessory is also reused. So when you scroll and don't remove the accessory from the cell it will still have the checkmark.
You could also reset the accessory in the prepareForReuse method in a custom UITableViewCell subclass
Add condition in cellForRowAtIndexPath
if([selectedDX containsObject:allCodeLabel[indexPath.row]])
{
cell.accessoryType = UITableViewCellAccessoryType.Checkmark
}
else
{
cell.accessoryType = UITableViewCellAccessoryType.None
}
It works for me.Hope it helps :)
you can handle it like this:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
WCategoriesTableViewCell* cell = [tableView
cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryNone)
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
}
I'm trying to make the selected cell (of a custom UITableViewCell) to have a checkmark on it. I tried the following code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
CategorieCell *customCell = [tableView dequeueReusableCellWithIdentifier:#"cellID" forIndexPath:indexPath];
if (customCell.accessoryType == UITableViewCellAccessoryDisclosureIndicator) {
customCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
customCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
But when I selected a cell, nothing happened.
Your mistake is that you dequeue a new custom cell. Instead, you have to find out the cell that actually is selected. Change the first line to:
CategorieCell *customCell = (CategorieCell *)[tableView cellForRowAtIndexPath:indexPath];
This should be it.
I'm getting a weird problem with table view in iOS. In the table, when I click on a row, I want a checkmark to be displayed, it is working very fine with the code below:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark){
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}else{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
}
Right now, my table has 11 rows. When I click on the 1st row, the checkmark appears for the 1st row (this is good) but it also appears for the 10th row. When I click on the 2nd row, the 2nd(this is good) and the 11th appears.
Does anyone has an idea about this issue?
Do this...
self.tableView.allowsMultipleSelection = YES;
Then when you need to get all the selected rows...
NSArray *selectedIndexPaths = [self.tableView indexPathsForSelectedRows];
This array will contain all the rows with the checkmarks on them.
No need to do anything in code yourself.
For the same thing what you are trying to do, I implemented it in following way -
Declare a NSIndexPath Variable in AppDelegate or in local file.
if (Appdelegate.selectedIndexPath == (id)[NSNull null]) {
NSLog(#"null");
Appdelegate.selectedWebsiteIndex=indexPath;
UITableViewCell *cell = [aTableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}else{
UITableViewCell *cell1 = [aTableView cellForRowAtIndexPath: Appdelegate.selectedIndexPath];
cell1.accessoryType = UITableViewCellAccessoryNone;
Appdelegate.selectedIndexPath =indexPath;
UITableViewCell *cell = [aTableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
Hope This helps you..
In my UITableView called _selectAttributes I want to put and remove a checkmark when I tap on each cell.
This is the code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell * cell = [_selectAttributes cellForRowAtIndexPath:indexPath];
if (cell.accessoryType != UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
Everything seems to work well, but when I scroll up and down the table, checkmarks appear on other cells and disappear on the previous ones.
How can I solve?
Thank you in advance.
Declare an NSIndexPath property named selectedIndexPath.
Then have your delegate methods cellForRowAtIndexPath and didSelectRowAtIndexPath like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
if ([indexPath isEqual:self.selectedIndexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:self.selectedIndexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
self.selectedIndexPath = indexPath;
}
UPDATE:
I wasn't paying attention that you want solution for multiple cell selection. My answer obviously solves problem only for single cell selection, but I believe its a good start.
I would create an NSArray of selected index paths. On tableView:didSelectRowAtIndexPath:, add the index path to that array and in tableView:cellForRowAtIndexPath: check whether the index path is in the array and set the UITableViewCell's accessory type accordingly.
When adding a checkmark to selected table cells, im seeing check appear in other cells also.
my didSelectRowAtIndexPathCode is:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
PFObject *player = [squadListArray objectAtIndex:indexPath.row];
NSString *playerName = [player valueForKey:#"fullName"];
NSLog(#"%#", playerName);
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
The NSLog has expect results, only showing the one selection.
Any ideas? Do you need me to show any other code?
Thanks
In your cellForRowAtIndexPath you can't be configuring the cell properly when the cell gets reused. You should always be setting (and resetting) all of the properties of the cell from your data model.
You must have a data model that is being used to tell the table view how many rows it has and what each cell should look like. During didSelectRowAtIndexPath you should be updating your data model with the selected information. Then, in cellForRowAtIndexPath, you can use the information in the data model to decide if the cell has a checkmark or not. If it does you add it, if it doesn't you explicitly remove it (to prevent it being left there if the cell was reused).
Your cell is being recycled by other rows. In the method, cellforrowatindexpath, add the following line at the end:
selectedCell.accessoryType = UITableViewCellAccessoryNone;
Cells are cached and re-used. You need to only save the fact you were selected (maybe in PFObject) and then set the accessory each time you configure a cell.
You need to explicitly tell that you don't want other cells to have the checkmark.
if ([self shouldSelectCell]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
You could try doing the following:
Create NSMutableSet that holds the indexes of selected cells.
#property(strong, nonatomic) NSMutableSet *selectedCells;
-(NSMutableSet *)selectedCells{
if(_selectedCells){
return _selectedCells;
}
_selectedCells = [[NSMutableSet alloc]init];
return _selectedCells;
}
On didSelect update the set and select the cell:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.selectedCells addObject:indexPath];
[tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];
}
Remove the indexPath on didDEselect
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
[self.selectedCells removeObject:indexPath];
}
Inside the
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
update the cell as:
if([self.selectedCells containsObject:indexPath]){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}else{
cell.accessoryType = UITableViewCellAccessoryNone;
}