Select one row in each section of UITableView ios?

谁说胖子不能爱 提交于 2019-12-01 10:08:42

问题


Scenario:

I have made 2 sections in one UITableView and the user needs to select a row in each section as shown in the screenshot below.

Expected Outcome: 1. User should be able to select a row in each section

Outcome right now: 1. After I have selected row in one section, and then when I select the row in second section, the first selection disappears.

Here is my code:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Uncheck the previous checked row

    long sec=indexPath.section;
     if(sec==0){
    if(self->checkedIndexPath)
    {
        UITableViewCell* uncheckCell = [tableView
                                        cellForRowAtIndexPath:self->checkedIndexPath];
        uncheckCell.accessoryType = UITableViewCellAccessoryNone;
    }
    if([self->checkedIndexPath isEqual:indexPath])
    {
        self->checkedIndexPath = nil;
    }
    else
    {
        UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        self->checkedIndexPath = indexPath;
    }}

    if(sec==1){

        if(self->checkedIndexPath)
        {
            UITableViewCell* uncheckCell = [tableView
                                            cellForRowAtIndexPath:self->checkedIndexPath];
            uncheckCell.accessoryType = UITableViewCellAccessoryNone;
        }
        if([self->checkedIndexPath isEqual:indexPath])
        {
            self->checkedIndexPath = nil;
        }
        else
        {
            UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
            self->checkedIndexPath = indexPath;
        }

    }

}

Help is appreciated.


回答1:


This is the simplest way. Finally i found a solution. It works for me, hope it will work for you. declare these

@interface ViewController ()
{
    int selectedsection;
    NSMutableArray *selectedindex;

}

Replace didSelectRowAtIndexPath as follows:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Uncheck the previous checked row

    NSIndexPath *selectedIndexPath = [tableView indexPathForSelectedRow];

        if(self.checkedIndexPath)

        {

            for (int i=0; i<[selectedindex count]; i++) {

                NSIndexPath *temp= [selectedindex objectAtIndex:i];
                if (temp.section==selectedIndexPath.section) {
                    UITableViewCell* uncheckCell = [tableView
                                                    cellForRowAtIndexPath:temp];
                    uncheckCell.accessoryType = UITableViewCellAccessoryNone;

                }
            }

            NSInteger numb= [tableView numberOfRowsInSection:selectedIndexPath.section];

            if (selectedsection==selectedIndexPath.section) {


            UITableViewCell* uncheckCell = [tableView
                                            cellForRowAtIndexPath:self.checkedIndexPath];
            uncheckCell.accessoryType = UITableViewCellAccessoryNone;

            }
        }



        if([self.checkedIndexPath isEqual:indexPath])
        {
            for (int i=0; i<[selectedindex count]; i++) {

                NSIndexPath *temp= [selectedindex objectAtIndex:i];
                if (temp.section==selectedIndexPath.section) {
                    UITableViewCell* uncheckCell = [tableView
                                                    cellForRowAtIndexPath:temp];
                    uncheckCell.accessoryType = UITableViewCellAccessoryNone;

                }
            }


           self.checkedIndexPath = nil;
        }
        else
        {
            for (int i=0; i<[selectedindex count]; i++) {

                NSIndexPath *temp= [selectedindex objectAtIndex:i];
                if (temp.section==selectedIndexPath.section) {
                    UITableViewCell* uncheckCell = [tableView
                                                    cellForRowAtIndexPath:temp];
                    uncheckCell.accessoryType = UITableViewCellAccessoryNone;

                }
            }

            UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
            self.checkedIndexPath = indexPath;
            [selectedindex addObject:indexPath];
            selectedsection=indexPath.section;

            NSLog(@"check");
        }






}



回答2:


You can enable the multiple selection in the tableview:

self.tableView.allowsMultipleSelection = YES;



回答3:


I wrote a sample code where a compound datasource holds datasource objects for each section. Sounds complicated but actually provides an easy to extend architecture. And keeps your view controller small.

The advantages of this approach:

  • Small ViewController
  • ViewController set ups view and handles user interaction — as it should be in MVC
  • Reusable datasources
  • by using different datasources per section easy to customize cells for each section

the base datasource architecture

This provides easy extension and is simple to reuse.


@import UIKit;

@interface ComoundTableViewDataSource : NSObject
@property (nonatomic,strong, readonly) NSMutableDictionary *internalDictionary;


-(void) setDataSource:(id<UITableViewDataSource>)dataSource forSection:(NSUInteger)section;
-(instancetype)initWithTableView:(UITableView *)tableView;
@end

#import "ComoundTableViewDataSource.h"


@interface ComoundTableViewDataSource () <UITableViewDataSource>
@property (nonatomic,strong, readwrite) NSMutableDictionary *internalDictionary;
@property (nonatomic, weak) UITableView *tableView;
@end

@implementation ComoundTableViewDataSource
-(instancetype)initWithTableView:(UITableView *)tableView
{
    self = [super init];
    if (self) {
        _tableView = tableView;
        tableView.dataSource = self;
        _internalDictionary = [@{} mutableCopy];
        [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];

    }
    return self;
}

-(void)setDataSource:(id<UITableViewDataSource>)dataSource forSection:(NSUInteger)section
{
    self.internalDictionary[@(section)] = dataSource;
    [self.tableView reloadData];

}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [[self.internalDictionary allKeys] count];
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    id<UITableViewDataSource> sectionDataSource = self.internalDictionary[@(section)];
    return [sectionDataSource tableView:tableView numberOfRowsInSection:section];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    id<UITableViewDataSource> sectionDataSource = self.internalDictionary[@(indexPath.section)];
    return [sectionDataSource tableView:tableView cellForRowAtIndexPath:indexPath];

}


-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    id<UITableViewDataSource> sectionDataSource = self.internalDictionary[@(section)];
    return [sectionDataSource tableView:tableView titleForHeaderInSection:section];
}
@end

@import UIKit;

@interface SingleSectionDataSource : NSObject <UITableViewDataSource>
@property (nonatomic, strong, readonly) NSArray *array;
@property (nonatomic, strong, readonly) UITableView *tableView;

- (instancetype)initWithArray:(NSArray *)array;
@end

#import "SingleSectionDataSource.h"

@interface SingleSectionDataSource ()
@property (nonatomic, strong, readwrite) NSArray *array;
@property (nonatomic, strong, readwrite) UITableView *tableView;

@end

@implementation SingleSectionDataSource

- (instancetype)initWithArray:(NSArray *)array
{
    self = [super init];
    if (self) {
        self.array = array;
    }
    return self;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    self.tableView = tableView;
    return self.array.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    cell.textLabel.text = self.array[indexPath.row];
    return cell;
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return [@(section) stringValue];
}

@end

the selection datasource architecture

We extend the classes from above to allow one selection per section

#import "ComoundTableViewDataSource.h"

@interface OnSelectionPerSectionComoundTableViewDataSource : ComoundTableViewDataSource
-(void)selectedCellAtIndexPath:(NSIndexPath *)indexPath;

@end

#import "OnSelectionPerSectionComoundTableViewDataSource.h"
#import "SingleSelectionSingleSectionDataSource.h"

@implementation OnSelectionPerSectionComoundTableViewDataSource


-(instancetype)initWithTableView:(UITableView *)tableView
{
    self = [super initWithTableView:tableView];
    if(self){
        [tableView setAllowsMultipleSelection:YES];
    }
    return self;
}

-(void)selectedCellAtIndexPath:(NSIndexPath *)indexPath
{
    SingleSelectionSingleSectionDataSource *sectionDataSource = self.internalDictionary[@(indexPath.section)];
    [sectionDataSource selectedCellAtIndexPath:indexPath];
}
@end

View Controller Implementation

As promised, a very slim view controller:

@interface ViewController () <UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic, strong) OnSelectionPerSectionComoundTableViewDataSource *tableViewDataSource;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableViewDataSource = [[OnSelectionPerSectionComoundTableViewDataSource alloc] initWithTableView:self.tableView];
    self.tableView.delegate = self;
    [self.tableViewDataSource setDataSource:[[SingleSelectionSingleSectionDataSource alloc] initWithArray:@[@"Hallo", @"Welt"]] forSection:0];
    [self.tableViewDataSource setDataSource:[[SingleSelectionSingleSectionDataSource alloc] initWithArray:@[@"Hello", @"World", @"!"]] forSection:1];
    [self.tableViewDataSource setDataSource:[[SingleSelectionSingleSectionDataSource alloc] initWithArray:@[@"Hola", @"Mundo", @"!", @"¿Que tal?"]] forSection:2];
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self.tableViewDataSource selectedCellAtIndexPath:indexPath];
}
@end

You will want to add methods to the datasources to get the selected rows.

get the example: https://github.com/vikingosegundo/CompoundDatasourceExample

Note This code has a cell reuse issue. It is fixed on GitHub.



来源:https://stackoverflow.com/questions/27838390/select-one-row-in-each-section-of-uitableview-ios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!