在UITableView ios的每个部分中选择一行?

Posted

技术标签:

【中文标题】在UITableView ios的每个部分中选择一行?【英文标题】:Select one row in each section of 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;
        

    


感谢您的帮助。

【问题讨论】:

【参考方案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 上修复。

【讨论】:

以上是关于在UITableView ios的每个部分中选择一行?的主要内容,如果未能解决你的问题,请参考以下文章

IOS:选择UIScrollView或UITableView

UITableView swift IOS分组部分中的重复值

带有 2 个部分选择的 UITableview

如何在 UITests 中选择 UITableView 的一部分?

iOS 程序在单个 UIViewController 中使用多个 UITableView

选择行其他部分在 UITableview 中包含相同的值?