【问题标题】:Select one row in each section of UITableView ios?在UITableView ios的每个部分中选择一行?
【发布时间】:2015-01-08 10:55:30
【问题描述】:

场景:

我在一个 UITableView 中创建了 2 个部分,用户需要在每个部分中选择一行,如下面的屏幕截图所示。

预期结果: 1.用户应该能够在每个部分中选择一行

现在的结果: 1.在我选择了一个部分中的行之后,然后当我选择第二部分中的行时,第一个选择消失了。

这是我的代码:

- (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;
        }

    }

}

感谢您的帮助。

【问题讨论】:

    标签: ios objective-c uitableview didselectrowatindexpath


    【解决方案1】:

    这是最简单的方法。 最后我找到了解决方案。它对我有用,希望它对你有用。 声明这些

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

    如下替换didSelectRowAtIndexPath:

    - (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");
            }
    
    
    
    
    
    
    }
    

    【讨论】:

    • 非常感谢@Sabrina,它对我来说工作正常,正是我想要的。
    • 滚动tableview选中的单元格后选择将被禁用,请您发布“cellForRowAtIndexPath”代码。
    【解决方案2】:

    您可以在表格视图中启用多选:

    self.tableView.allowsMultipleSelection = YES;
    

    【讨论】:

    • 感谢您的回复,我希望在每个部分中只勾选一行。
    • 您应该跟踪每个部分中的选择,如果该行中已经选择了某些内容,请取消选择
    【解决方案3】:

    我编写了一个示例代码,其中复合数据源包含每个部分的数据源对象。听起来很复杂,但实际上提供了一种易于扩展的架构。并保持您的视图控制器很小。

    这种方法的优点:

    • 小视图控制器
    • ViewController 设置视图并处理用户交互——就像在 MVC 中一样
    • 可重用的数据源
    • 通过在每个部分使用不同的数据源,轻松自定义每个部分的单元格

    基础数据源架构

    这提供了简单的扩展并且易于重复使用。


    @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
    

    选择数据源架构

    我们从上面扩展类以允许每个部分选择一个

    #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
    

    查看控制器实现

    正如所承诺的,一个非常纤薄的视图控制器:

    @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
    

    您需要向数据源添加方法以获取选定的行。

    获取示例:https://github.com/vikingosegundo/CompoundDatasourceExample

    注意此代码存在单元重用问题。它已在 GitHub 上修复。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-24
      • 2013-01-11
      • 1970-01-01
      • 1970-01-01
      • 2016-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多