Ios 可在每个部分中选择项目的限制数量

Ios 可在每个部分中选择项目的限制数量,ios,objective-c,uitableview,Ios,Objective C,Uitableview,我在下面的实现中遇到了一个问题。我定义了在tableview的每个部分中可以选择的最大项目数 假设用户只允许选择0部分中的两个项目。如果用户试图选择第三个附件,则将取消选择第一个所选项目,并且第三个项目将带有复选标记 我的以下实现无法处理,它允许两个以上带有所有复选标记的项。我想知道我哪里做错了 -(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath

我在下面的实现中遇到了一个问题。我定义了在tableview的每个部分中可以选择的最大项目数

假设用户只允许选择0部分中的两个项目。如果用户试图选择第三个附件,则将取消选择第一个所选项目,并且第三个项目将带有复选标记

我的以下实现无法处理,它允许两个以上带有所有复选标记的项。我想知道我哪里做错了

-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    int numberOfItemsSelected = [[selectedRowsInSectionDictionary valueForKey: [NSString stringWithFormat:@"%ld",indexPath.section]] intValue];

    if(((ComboItem*)comboItemsArray[indexPath.section]).itemNumberEachCombo == numberOfItemsSelected)
    {
        NSIndexPath *oldIndex = [self.comboTableView indexPathForSelectedRow];
        [self.comboTableView cellForRowAtIndexPath:oldIndex].accessoryType = UITableViewCellAccessoryNone;
        [self.comboTableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
        return nil;
    }
    else
    {
        return indexPath;
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath   *)indexPath
{
    [comboTableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
    [self selectedItem:self.comboTableView];
}

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [comboTableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
    [self selectedItem:self.comboTableView];
}

- (void)selectedItem: (UITableView *)tableView {
    selectedRowsInSectionDictionary = [NSMutableDictionary dictionary];
    NSArray <NSIndexPath*> *selectedIndexPaths = [tableView indexPathsForSelectedRows];
    for (NSIndexPath *indexpath in selectedIndexPaths) {
        NSString *sectionKey = [NSString stringWithFormat:@"%ld",indexpath.section];
        NSInteger numberOfSelectedRows = [[selectedRowsInSectionDictionary objectForKey: sectionKey] integerValue];
        numberOfSelectedRows++;
        [selectedRowsInSectionDictionary setObject:@(numberOfSelectedRows) forKey: sectionKey];
    }
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    if([[tableView indexPathsForSelectedRows] containsObject:indexPath]) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }

    cell.textLabel.text =  ((ComboItem*)comboItemsArray[indexPath.section]).allComboItems[indexPath.row];
    return cell;
}
-(nsindepath*)tableView:(UITableView*)tableView将选择rowatindexpath:(nsindepath*)indepath{
int numberOfItemsSelected=[[selectedRowsInSectionDictionary valueForKey:[NSString stringWithFormat:@“%ld”,indexath.section]]intValue];
if(((ComboItem*)comboItemsArray[indexath.section]).ItemNumberReachCombo==numberOfItemsSelected)
{
NSIndexPath*oldIndex=[self.comboTableView indexPathForSelectedRow];
[self.comboTableView cellForRowAtIndexPath:oldIndex].accessoryType=UITableViewCellAccessoryNone;
[self.comboTableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryCheckmark;
返回零;
}
其他的
{
返回索引XPath;
}
}
-(void)tableView:(UITableView*)tableView未选择RowatineXpath:(NSIndexPath*)indexPath
{
[comboTableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryCheckmark;
[self-selectedItem:self.comboTableView];
}
-(void)tableView:(UITableView*)tableView未取消行索引路径:(NSIndexPath*)索引路径
{
[comboTableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryNone;
[self-selectedItem:self.comboTableView];
}
-(无效)选择编辑项:(UITableView*)表格视图{
selectedRowsInSectionDictionary=[NSMutableDictionary];
NSArray*selectedIndexPaths=[tableView IndExpathForSelectedRows];
for(选定索引路径中的NSIndexPath*indexpath){
NSString*sectionKey=[NSString stringWithFormat:@“%ld”,indexath.section];
NSInteger numberOfSelectedRows=[[selectedRowsInSectionDictionary objectForKey:sectionKey]integerValue];
选择的行数++;
[selectedRowsInSectionDictionary setObject:@(numberOfSelectedRows)forKey:sectionKey];
}
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
静态NSString*cellIdentifier=@“Cell”;
UITableViewCell*单元格=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
如果(单元格==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault重用标识符:cellIdentifier];
}
如果([[tableView IndExpathForSelectedRows]包含对象:indexPath]){
cell.accessoryType=UITableViewCellAccessoryCheckmark;
}否则{
cell.accessoryType=UITableViewCellAccessoryNone;
}
cell.textlab.text=((ComboItem*)comboItemsArray[indexPath.section]).allComboItems[indexPath.row];
返回单元;
}
编辑:(在我的示例项目上尝试后)

willSelectRowatineXpath:
方法的实现在我看来不正确。另外,
indexPathForSelectedRow
返回行选择数组中的第一个索引路径对象;因此,始终返回第0节的第一个选定索引

这是在删除方法-
(void)selectedItem:(UITableView*)tableView
和selectedRowsInSectionDictionary变量并添加一个新的NSMutable dictionary变量以维护所选索引路径数组之后的实现,
selectedIndexPathsInSectionDictionary

- (void)viewDidLoad {
    [super viewDidLoad];
    selectedIndexPathsInSectionDictionary = [NSMutableDictionary dictionary];
    // Do any additional setup after loading the view, typically from a nib.
}

    -(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        int numberOfItemsSelected = [[selectedIndexPathsInSectionDictionary objectForKey:@(indexPath.section)] count];

        if(((ComboItem*)comboItemsArray[indexPath.section]).itemNumberEachCombo == numberOfItemsSelected)
        {
            NSIndexPath *oldIndex = [[selectedIndexPathsInSectionDictionary objectForKey:@(indexPath.section)] firstObject];
            [tableView deselectRowAtIndexPath:oldIndex animated:NO];
            [self tableView:tableView didDeselectRowAtIndexPath:oldIndex];
        }
         return indexPath;
    }

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath   *)indexPath
    {
        [comboTableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
        [self selectItemAtIndexPath:indexPath];
    }

    -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [comboTableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
        [self deselectItemAtIndexPath:indexPath];
    }

    - (void)selectItemAtIndexPath:(NSIndexPath *)indexPath  {
        NSMutableArray* array = [selectedIndexPathsInSectionDictionary objectForKey:@(indexPath.section)];
        if(array){
            [array addObject:indexPath];
        } else {
            array = [NSMutableArray array];
            [array addObject:indexPath];
            [selectedIndexPathsInSectionDictionary setObject:array forKey:@(indexPath.section)];
        }
    }

    - (void)deselectItemAtIndexPath:(NSIndexPath*)indexPath {
        NSMutableArray* array = [selectedIndexPathsInSectionDictionary objectForKey:@(indexPath.section)];
        [array removeObject:indexPath];
    }

示例项目的编辑:
(在我的示例项目上尝试后)

willSelectRowatineXpath:
方法的实现在我看来不正确。另外,
indexPathForSelectedRow
返回行选择数组中的第一个索引路径对象;因此,始终返回第0节的第一个选定索引

这是在删除方法-
(void)selectedItem:(UITableView*)tableView
和selectedRowsInSectionDictionary变量并添加一个新的NSMutable dictionary变量以维护所选索引路径数组之后的实现,
selectedIndexPathsInSectionDictionary

- (void)viewDidLoad {
    [super viewDidLoad];
    selectedIndexPathsInSectionDictionary = [NSMutableDictionary dictionary];
    // Do any additional setup after loading the view, typically from a nib.
}

    -(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        int numberOfItemsSelected = [[selectedIndexPathsInSectionDictionary objectForKey:@(indexPath.section)] count];

        if(((ComboItem*)comboItemsArray[indexPath.section]).itemNumberEachCombo == numberOfItemsSelected)
        {
            NSIndexPath *oldIndex = [[selectedIndexPathsInSectionDictionary objectForKey:@(indexPath.section)] firstObject];
            [tableView deselectRowAtIndexPath:oldIndex animated:NO];
            [self tableView:tableView didDeselectRowAtIndexPath:oldIndex];
        }
         return indexPath;
    }

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath   *)indexPath
    {
        [comboTableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
        [self selectItemAtIndexPath:indexPath];
    }

    -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [comboTableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
        [self deselectItemAtIndexPath:indexPath];
    }

    - (void)selectItemAtIndexPath:(NSIndexPath *)indexPath  {
        NSMutableArray* array = [selectedIndexPathsInSectionDictionary objectForKey:@(indexPath.section)];
        if(array){
            [array addObject:indexPath];
        } else {
            array = [NSMutableArray array];
            [array addObject:indexPath];
            [selectedIndexPathsInSectionDictionary setObject:array forKey:@(indexPath.section)];
        }
    }

    - (void)deselectItemAtIndexPath:(NSIndexPath*)indexPath {
        NSMutableArray* array = [selectedIndexPathsInSectionDictionary objectForKey:@(indexPath.section)];
        [array removeObject:indexPath];
    }


示例项目的

添加cellForRowAtindexpath方法。我刚刚包括。添加cellForRowAtindexpath方法。我刚刚包括。出于某些原因,每当第二节项达到最大数量时,它也会取消选择第一节的项。这很奇怪。知道吗?知道了,indexPathForSelectedRow总是返回行选择数组中的第一个索引路径对象;因此,始终返回第0节的第一个选定索引,使得逻辑有缺陷。最好是维护一个所选索引路径的字典,其中键为section,索引路径数组为value。您可以将其添加到您的答案中吗?我已经有了这个逻辑(跟踪字典中每个部分的选定indexPath,-
(void)selectedItem:(UITableView*)tableView
但我该如何使用它?@HotSping:上面的实现在我的示例项目中起作用了我在床上给你写信,我早上第一件事就是要检查你的代码。我刚刚投了赞成票,一旦我检查了,我会标记为答案。如果你将你的示例项目上传到github并链接它,我会非常高兴。那就是我们对于其他人也是如此。出于某些原因,每当第二节的项达到最大值时,它也会取消选择第一节的项。这很奇怪。知道吗?知道了,我知道了,indexPathForSelectedRow总是返回数组中的第一个索引路径对象