Bug when I try to check only one cell in tableview - ios

When I check the first cell after loading – nothing happens, I’m tapping over and over again – nothing happens. I can check other cells, the second, the third etc. and only after that I can check the first cell. This is my method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = indexPath.row;
NSUInteger oldRow = lastIndexPath.row;
if (oldRow != row) {
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
lastIndexPath = indexPath;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Or maybe you can advise other way to make it (checking only one cell in tableview), because I've found only models with a lot of code and hard to understand.

It is because at first your lastIndexPath variable is nil, so lastIndexPath.row will return 0. If you tap on the first row, that row is also 0, so it won't enter the if statement. Replace that statement with: if (!lastIndexPath || oldRow != row)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell;
//cell creation code
cell.accessoryType = nil != lastIndexPath && lastIndexPath.row == indexPath.row ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray* reloadRows = nil == lastIndexPath ? #[indexPath] : #[lastIndexPath, indexPath];
lastIndexPath = indexPath;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[tableView reloadRowsAtIndexPaths:reloadRows withRowAnimation: UITableViewRowAnimationAutomatic];
}

Related

How To Get TableviewCell Selected Check Mark Row Values Using Objective C?

I need to create tableviewcell checkmark selected row title label and detail label values get after clicking the submit button.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil )
{
cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if ([indexPath compare:self.lastIndexPath] == NSOrderedSame)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
// UITableView Delegate Method
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"Section:%ld Row:%ld selected and its data is %# %#",(long)indexPath.section,(long)indexPath.row,cell.sector_Label.text,cell.textLabel.text);
selectedIndex = indexPath.row;
[tableView reloadData];
}
- (IBAction)Submit_Click:(id)sender {
// Here I need to get tableview cell check mark selected cell label values.
}
Check this:
-(IBAction)Submit_Click:(id)sender {
// Here I need to get tableview cell check mark selected cell label values.
if (selectedIndex >= 0) {
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:selectedIndex inSection:0];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"detailTextLabel: %#", cell.detailTextLabel.text);
NSLog(#"title: %#", cell.textLabel.text);
}
}
You can use indexPathsForSelectedRows
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.isSelected)
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
else
{
[cell setSelected:YES animated:YES]
}
}
-(IBAction)Submit_Click:(id)sender {
// Here I need to get tableview cell check mark selected cell label values.
NSArray *indexes = [self.tableview indexPathsForSelectedRows];
if (indexes.count > 0)
{
//do your stuff as you get selected row index array
}
}

Checkmark on cell of UITableView

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.

Probable Bug in tableview

I have a UITablViewController and implementing the following :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tableView cellForRowAtIndexPath:self.oldIndexPath].accessoryType = UITableViewCellAccessoryNone;
NSLog(#"%#", indexPath);
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.oldIndexPath = indexPath;
}
What I notice is, the checkmark appears on 2 cells, one with index path, for example, if I select a cell with index path {length = 2, path = 0 - 2} and scrolling down I notice the checkmark is also visible on {length = 2, path = 0 - 14}
There is just 1 section in the table view and around 18-19 rows.
Can somebody verify this for me / or is it time for me to get some sleep :/ ?
P.S : tested this on simulator and device
The cells are created as follows :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
cell.textLabel.text = self.stationsDictionary[#"urls"][indexPath.row][#"title"];
return cell;
}
Since your cells are reusable (I suppose), you need to set this in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tableView cellForRowAtIndexPath:self.oldIndexPath].accessoryType = UITableViewCellAccessoryNone;
NSLog(#"%#", indexPath);
self.oldIndexPath = indexPath;
for (UITableViewCell *cell in tableView.visibleCells) {
if ([tableView indexPathForCell:cell].section == indexPath.section && [tableView indexPathForCell:cell].row == indexPath.row) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
}
and
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
cell.textLabel.text = self.stationsDictionary[#"urls"][indexPath.row][#"title"]; return cell;
cell.accessoryType = self.oldIndexPath.section == indexPath.section && self.oldIndexPath.row == indexPath.row ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
}
Or the reused cell will keep the state of the previous cell (the one reused) which can be checked.
Common error ;)
When you dequeue a cell from cellForRowAtIndexPath, be sure to reset its status - in your case, the accessoryType property.
Since cells are reused, what happens is that when cell with index 2 is not visible, it is reused to display row with index 14.
As a consequence of that, you need to save each cell state if you want to preserve its status (in your case in didSelectRowAtIndexPath if you only need to save the accessoryType property), and restore into the cell in cellForRowAtIndexPath.
You can use an NSArray, using the cell index as array index, to save your cell status, or even a "normal" array of UITableViewCellAccessoryType or booleans

How to properly toggle UITableViewCell's accesoryType on cell selection/deselection?

I'm trying to toggle accesoryType when a table cell is selected/deselected... the behavior should be: tap -> set accessoryType to UITableViewCellAccessoryCheckmark -> tap the cell again -> rollback to UITableViewCellAccessoryNone type.
The implementation in my controller is the following:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
...anyway once the style is configured as UITableViewCellAccessoryCheckmark I'm unable to restore it back to UITableViewCellAccessoryNone!
I also tried to call:
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
but does not remove the checkmark... what should I do?
EDIT: The implementation is ok, the problem was in the custom UITableViewCell subclass... sorry :P
Try this if this is what you want
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark)
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
If you want to have only one row as checkmark use this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = (cell.accessoryType == UITableViewCellAccessoryCheckmark) ? UITableViewCellAccessoryNone : UITableViewCellAccessoryCheckmark;
if (_lastSelectedIndexPath != nil)
{
UITableViewCell *lastSelectedCell = [tableView cellForRowAtIndexPath:_lastSelectedIndexPath];
lastSelectedCell.accessoryType = UITableViewCellAccessoryNone;
}
_lastSelectedIndexPath = indexPath;
}
Tapping the cell again equates to selection of the cell and not deselection.
You need to have a toggle in the - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath method to check if the cell.accessoryType == UITableViewCellAccessoryCheckmark.
- (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)newIndexPath {
[theTableView deselectRowAtIndexPath:[theTableView indexPathForSelectedRow] animated:NO];
UITableViewCell *cell = [theTableView cellForRowAtIndexPath:newIndexPath];
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
// Reflect selection in data model
} else if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
// Reflect deselection in data model
}
}

Table View Did Select Row

So i have a tableView with checkmark accessory type and I have such method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger newRow = [lastIndexPath row];
NSUInteger oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
if (newRow != oldRow) {
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
lastIndexPath = indexPath;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
And it seems to work fine for the first time, but when I select the row for the second time it throws me out and says EXC_BAD_ACCESS. and when I switch the simulator to 4.3, it selects the row only ones and then doesn't work. Can anybody help?
Use self.lastIndexPath = indexPath if you have a #property declared for lastIndexPAth.

Resources