1

Spent hours and hours and no use.I don't understand whether I was not effective in searching(googling) or is it that there are less questions on this or I might have committed some mistake while implementing the answers of experts!

I know there are several questions on setting accessory type check mark for one row and none for other rows in a section,traced out posts here and there.

I have 2 sections in my table view.By default I want the 1st row in each section to be selected i.e. with accessory view check mark.Now from here upon user selection of a row,I want the check mark to be visible on selected row only.I have tried declaring two index paths to keep track of row selection in each section.Here is my implementation code:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{    
    NSString *cellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.row,indexPath.section];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (indexPath.section == 0)
    {
        if(self.firstSectionIndex == indexPath)
        {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
        else
        {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
    }

    if (indexPath.section == 1)
    {
        if(self.secondSectionIndex == indexPath)
        {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
        else
        {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
    }

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
        cell.backgroundColor = [UIColor clearColor];
        cell.textLabel.textColor = [UIColor whiteColor];

        switch (indexPath.section)
        {
            case 0:
            {
                if (indexPath.row == 0)
                {
                    if(self.firstSectionIndex != indexPath)
                    {
                        cell.accessoryType = UITableViewCellAccessoryCheckmark;
                    }
                    else
                    {
                        cell.accessoryType = UITableViewCellAccessoryNone;
                    }
                    cell.textLabel.text = @"Yes";
                }
                if (indexPath.row == 1)
                {
                    cell.textLabel.text = @"No";
                }
            }
                break;
            case 1:
            {
                if (indexPath.row == 0)
                {
                    if(self.secondSectionIndex != indexPath)
                    {
                        cell.accessoryType = UITableViewCellAccessoryCheckmark;
                    }
                    else
                    {
                        cell.accessoryType = UITableViewCellAccessoryNone;
                    }
                    cell.textLabel.text = @"Easy";
                }
                if (indexPath.row == 1)
                {
                    cell.textLabel.text = @"Medium";
                }
                if (indexPath.row == 2)
                {
                    cell.textLabel.text = @"Hard";
                }
            }
                break;

            default:
                break;
        }
    }

    tableView.backgroundColor = [UIColor clearColor];
    tableView.backgroundView = nil;

    return cell;
}

in my didSelectRowAtIndexPath,I have done the following:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0)
    {
      self.firstSectionIndex = indexPath;
    }
    if (indexPath.section == 1)
    {
       self.secondSectionIndex = indexPath;
    }
    [tableView reloadData];
}

I have searched for the state of cell selection to be saved for long term reference,in quest of it,I found some useful link here.

But it is selecting multiple cells and accessory type check mark is being applied for all rows in section.I don't understand what's wrong.Can any one please guide me on this!!

Thanks all in advance :)

Community
  • 1
  • 1
Eshwar Chaitanya
  • 942
  • 2
  • 13
  • 34

4 Answers4

3

you can achieve it using this bellow implementation of code :-

EDITED

.h file

NSMutableArray *firstSelectedCellsArray;
NSMutableArray *secondSelectedCellsArray;
NSMutableArray *ThirdSelectedCellsArray;

in .m file

    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0)
    {
        NSNumber *rowNumber = [NSNumber numberWithUnsignedInt:indexPath.row];

        UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
        if (selectedCell.accessoryType == UITableViewCellAccessoryNone)
        {
            selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
            if ( [firstSelectedCellsArray containsObject:rowNumber]  )
            {
                [firstSelectedCellsArray removeObject:rowNumber];
            }
            else
            {
                [firstSelectedCellsArray addObject:rowNumber];
            }
        }
        else if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark)
        {
            if ( [firstSelectedCellsArray containsObject:rowNumber]  )
            {
                [firstSelectedCellsArray removeObject:rowNumber];
            }
            else
            {
                [firstSelectedCellsArray addObject:rowNumber];
            }
            selectedCell.accessoryType = UITableViewCellAccessoryNone;
        }
    }

    if (indexPath.section == 1)
    {
        NSNumber *rowNumber = [NSNumber numberWithUnsignedInt:indexPath.row];

        UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
        if (selectedCell.accessoryType == UITableViewCellAccessoryNone)
        {
            selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
            if ( [secondSelectedCellsArray containsObject:rowNumber]  )
            {
                [secondSelectedCellsArray removeObject:rowNumber];
            }
            else
            {
                [secondSelectedCellsArray addObject:rowNumber];
            }
        }
        else if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark)
        {
            if ( [secondSelectedCellsArray containsObject:rowNumber]  )
            {
                [secondSelectedCellsArray removeObject:rowNumber];
            }
            else
            {
                [secondSelectedCellsArray addObject:rowNumber];
            }
            selectedCell.accessoryType = UITableViewCellAccessoryNone;
        }
    }
    if (indexPath.section == 2)
    {
        NSNumber *rowNumber = [NSNumber numberWithUnsignedInt:indexPath.row];

        UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
        if (selectedCell.accessoryType == UITableViewCellAccessoryNone)
        {
            selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
            if ( [ThirdSelectedCellsArray containsObject:rowNumber]  )
            {
                [ThirdSelectedCellsArray removeObject:rowNumber];
            }
            else
            {
                [ThirdSelectedCellsArray addObject:rowNumber];
            }
        }
        else if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark)
        {
            if ( [ThirdSelectedCellsArray containsObject:rowNumber]  )
            {
                [ThirdSelectedCellsArray removeObject:rowNumber];
            }
            else
            {
                [ThirdSelectedCellsArray addObject:rowNumber];
            }
            selectedCell.accessoryType = UITableViewCellAccessoryNone;
        }
    }

}

NOW in cellForRowAtIndexPath put littel piece of code:-

 - (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.section==0)
    {

        NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];
        if ( [firstSelectedCellsArray containsObject:rowNsNum]  )
        {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
        else
        {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
    }
    if(indexPath.section==1)
    {

        NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];
        if ( [secondSelectedCellsArray containsObject:rowNsNum]  )
        {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
        else
        {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
    }
    if(indexPath.section==2)
    {

        NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];
        if ( [ThirdSelectedCellsArray containsObject:rowNsNum]  )
        {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
        else
        {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
    }

    return cell;
}

DEMO LINK

http://www.sendspace.com/file/z6oxg2

ScreenShot:

enter image description here

Nitin Gohel
  • 49,482
  • 17
  • 105
  • 144
  • Thank you so much for the answer,but how about initially setting check mark for 1st row in both the sections.Also I observe in your code,NSIndexPath *checkedIndexPath isn't being used. – Eshwar Chaitanya May 14 '13 at 07:33
  • yes you are right sorry for that its unused variable. so as par your checking section vise you have to put as a section wise different Selected array for example you have to check first section like if(indexPath.section==0) that and then impliment as my answer – Nitin Gohel May 14 '13 at 07:36
  • Sorry to say,it is not working,I mean check mark is not getting applied,I don't know the reason why,here is my implementation code: http://pastebin.com/YWsRjAx6 – Eshwar Chaitanya May 14 '13 at 07:56
  • Sorry,when I removed [tableView reloadData] line,I could see multiple check marks i.e. previous cell check mark not disappearing after selecting another cell(row) ,updated code: http://pastebin.com/XF7V66Hf – Eshwar Chaitanya May 14 '13 at 08:20
  • i just impliment its in one tableview section demo please check my edited Answer and download this demo hope now u got it.. – Nitin Gohel May 14 '13 at 09:14
  • Sorry,as of now the net speed is a bit slow,link's not opening/taking too long to respond,can you please edit the answer by placing proper code snippets,please don't mind me troubling you :) – Eshwar Chaitanya May 14 '13 at 09:19
  • Sorry,I think I have confused you,I am getting check mark when a cell(row) is selected,but the previous cell's check mark is not disappearing,I mean if a cell is selected it should only show the check mark and not any other rows :) – Eshwar Chaitanya May 14 '13 at 10:30
  • Yes the example above also allows multiple cell selection(check marks for all cells),just now I have downloaded and tested,instead it should allow check mark for only selected cell – Eshwar Chaitanya May 14 '13 at 10:55
  • I have successfully implemented one check mark per one section,now I am trying to persist the check mark state,but I am unable to save and retrieve,here is my implementation code: http://pastebin.com/MmC6EcYu – Eshwar Chaitanya May 15 '13 at 07:52
  • You helped me out to get started and provided me with some useful code snippets and links,hence I gave +1,I have achieved one check mark per section and in fact saving the check mark state for future reference,hence please don't mind me accepting my own answer for that :) – Eshwar Chaitanya Jun 04 '13 at 04:46
2

I have found a precise and perfect solution,thanks to Lithu T.V and Nithin Gobel for guiding me in the right direction.Unfortunately their solutions didn't help me in achieving 1 check mark per section,but multiple check marks in fact.So I thought of saving the selected row in user defaults and for initially selecting 1st row of each section,we declare first and second section index,assign to index path and then assign cell accessory view as check mark.Here we go,let's first deal with cellForRowAtIndexPath:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.row,indexPath.section];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
        cell.backgroundColor = [UIColor clearColor];
        cell.textLabel.textColor = [UIColor whiteColor];
        NSUserDefaults *savedState = [NSUserDefaults standardUserDefaults];

        switch (indexPath.section)
        {
            case 0:
            {
                NSNumber *indexNumber = [NSNumber numberWithInteger:indexPath.row];
                if([[savedState objectForKey:@"firstSectionIndex"] isEqual: indexNumber])
                {
                    cell.accessoryType = UITableViewCellAccessoryCheckmark;
                    self.firstSectionIndex = indexPath;
                }

                if (indexPath.row == 0)
                {                    
                    NSObject * checkedCellObject = [savedState objectForKey:@"firstSectionIndex"];
                    if(checkedCellObject == nil)
                    {
                        self.firstSectionIndex = indexPath;
                        cell.accessoryType = UITableViewCellAccessoryCheckmark;
                    }
                    cell.textLabel.text = @"Yes";
                }
                if (indexPath.row == 1)
                {
                    cell.textLabel.text = @"No";
                }
            }
                break;
            case 1:
            {
                NSNumber *indexNumber = [NSNumber numberWithInteger:indexPath.row];
                if([[savedState objectForKey:@"secondSectionIndex"] isEqual: indexNumber])
                {
                    cell.accessoryType = UITableViewCellAccessoryCheckmark;
                    secondSectionIndex = indexPath;
                }

                if (indexPath.row == 0)
                {
                    NSObject * checkedCellObject = [savedState objectForKey:@"secondSectionIndex"];
                    if(checkedCellObject == nil)
                    {
                        cell.accessoryType = UITableViewCellAccessoryCheckmark;
                        secondSectionIndex = indexPath;
                    }
                    cell.textLabel.text = @"Easy";
                }
                if (indexPath.row == 1)
                {
                    cell.textLabel.text = @"Medium";
                }
                if (indexPath.row == 2)
                {
                    cell.textLabel.text = @"Hard";
                }
            }
                break;

            default:
                break;
        }
    }

    tableView.backgroundColor = [UIColor clearColor];
    tableView.backgroundView = nil;

    return cell;
}

Please observe in each case,we are checking if the checked state is in saved user defaults,if it is nil,we check 1st cell(row) of each section,here we go with table view delegate method,did select row at index path:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    if (indexPath.section == 0)
    {
        UITableViewCell *checkCell = [tableView cellForRowAtIndexPath:indexPath];
        if(firstSectionIndex && firstSectionIndex != indexPath)
        {
            UITableViewCell *uncheckCell = [tableView cellForRowAtIndexPath:firstSectionIndex];
            uncheckCell.accessoryType = UITableViewCellAccessoryNone;
        }
        self.firstSectionIndex = indexPath;
        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:firstSectionIndex.row] forKey:@"firstSectionIndex"];
        checkCell.accessoryType = UITableViewCellAccessoryCheckmark;
    }

    if (indexPath.section == 1)
    {
        UITableViewCell *checkCell = [tableView cellForRowAtIndexPath:indexPath];
        if(secondSectionIndex)
        {
            UITableViewCell *unchekCell = [tableView cellForRowAtIndexPath:secondSectionIndex];
            unchekCell.accessoryType = UITableViewCellAccessoryNone;
        }
        self.secondSectionIndex = indexPath;
        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:secondSectionIndex.row] forKey:@"secondSectionIndex"];
        checkCell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
}

That's it,we have successfully accomplished one check mark per section and also save the accessory state of cell in user defaults for long term reference.

Hope this helps some one,thanks :)

Eshwar Chaitanya
  • 942
  • 2
  • 13
  • 34
1

for implementing checkmark

  1. Keep an index array for selected indexes
  2. In the cellFor Row method check if current indexpath is there in the selected index array.

if true

    cell.accessoryType = UITableViewCellAccessoryCheckmark;

else

    cell.accessoryType = UITableViewCellAccessoryNone;
  1. In didSelect method if checkmarked.Remove index from array as well as set the accessory type none
  2. If accessory none add the checkmark and add the index into array .

EDIT

In case what you need is the single selection everytime you select a cell remove all index from array and add that only and then reload tableview

Lithu T.V
  • 19,955
  • 12
  • 56
  • 101
  • I have implemented what you suggested,but it is not working as I had expected it to be,problem is facing multiple check marks problem i.e. previous cell check mark not disappearing after selecting another cell(row) ,my implementation code: http://pastebin.com/XF7V66Hf – Eshwar Chaitanya May 14 '13 at 08:21
  • I have added this line [self.array removeAllObjects] in did select row method,but still it is allowing multiple cell selection,check mark :( – Eshwar Chaitanya May 14 '13 at 09:14
  • Awaiting your response,yet to achieve the task :( – Eshwar Chaitanya May 14 '13 at 11:00
  • @EshwarChaitanya that is because you didnot reload table on the did select method – Lithu T.V May 14 '13 at 11:50
  • Sorry,but I have called reload data in did select row method – Eshwar Chaitanya May 14 '13 at 12:26
  • Please help me,I have successfully implemented one check mark per section in table view,also saved its state for future reference,but only problem I am facing is,when I select bottom cell(row of a section),then come back to view,select upper cell,it is showing check mark for both sections,but still I could see only one check mark when I navigate to another view and come back,here is my implementation code: http://pastebin.com/KF6NHw5x – Eshwar Chaitanya May 30 '13 at 06:39
  • Thanks for your stepping forward to help me Lithu,I am happy to say I solved my problem,since you guided me well and gave some ideas,I am giving +1,but please don't mind because I am accepting my answer :) – Eshwar Chaitanya Jun 04 '13 at 04:48
0

I have the similar requirement where I need to select a single option per section and show the tick mark and I have achieved the same with simple steps. You do not need to reload the section or table at all.

Step 1:

Keep a hash-table/dictionary to your model which keeps the record of selected IndexPath per section type.

Example -

class DeviceSettingModel {
  var indexPathSelectionDict: [DeviceSettingSectionType: IndexPath] = [:]
}

enum DeviceSettingSectionType: Int {
    case audioDevices
    case videoDevices
    case videoQualities 
}

Step 2:

Update the selection in tableView(didSelectAtRow) delegate:

Example -

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        guard let settingModel = settingModel,
            let type: DeviceSettingSectionType = DeviceSettingSectionType(rawValue: indexPath.section)
        else { return }

        // other data and view related updating...


        // unselect first on the same section.
        if let previousIndex = settingModel.indexPathSelectionDict[type] {
            if let cell = tableView.cellForRow(at: previousIndex) {
                cell.accessoryType = .none
            }
        }

        // update selected indexPath into the model and put a tick mark
        settingModel.indexPathSelectionDict[type] = indexPath
        if let cell = tableView.cellForRow(at: indexPath) {
            cell.accessoryType = .checkmark
        }

}

That's it, you can see below effect.

Select each device configuration section wise

Ashis Laha
  • 2,176
  • 3
  • 16
  • 17