Select one row in each section of UITableView ios?

前端 未结 3 670
慢半拍i
慢半拍i 2021-01-15 02:50

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:

相关标签:
3条回答
  • 2021-01-15 03:19

    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");
            }
    
    
    
    
    
    
    }
    
    0 讨论(0)
  • 2021-01-15 03:26

    You can enable the multiple selection in the tableview:

    self.tableView.allowsMultipleSelection = YES;
    
    0 讨论(0)
  • 2021-01-15 03:29

    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.

    0 讨论(0)
提交回复
热议问题