【问题标题】:Set one check mark for each section in UITableView and save its state为 UITableView 中的每个部分设置一个复选标记并保存其状态
【发布时间】:2013-05-14 07:08:43
【问题描述】:

花了好几个小时都没有用。我不明白我是否在搜索(谷歌搜索)方面没有效率,还是这方面的问题较少,或者我在执行专家的答案时可能犯了一些错误!

我知道有几个关于在一节中为一行设置附件类型复选标记而为其他行设置不复选标记的问题,追踪帖子herethere

我的表格视图中有 2 个部分。默认情况下,我希望选择每个部分中的第一行,即带有辅助视图复选标记。现在,在用户选择一行后,我希望复选标记可见仅在选定的行上。我尝试声明两个索引路径来跟踪每个部分中的行选择。这是我的实现代码:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{    
    NSString *cellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.row,indexPath.section];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (indexPath.section == 0)
    {
        if(self.firstSectionIndex == indexPath)
        {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
        else
        {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
    }

    if (indexPath.section == 1)
    {
        if(self.secondSectionIndex == indexPath)
        {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
        else
        {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
    }

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
        cell.backgroundColor = [UIColor clearColor];
        cell.textLabel.textColor = [UIColor whiteColor];

        switch (indexPath.section)
        {
            case 0:
            {
                if (indexPath.row == 0)
                {
                    if(self.firstSectionIndex != indexPath)
                    {
                        cell.accessoryType = UITableViewCellAccessoryCheckmark;
                    }
                    else
                    {
                        cell.accessoryType = UITableViewCellAccessoryNone;
                    }
                    cell.textLabel.text = @"Yes";
                }
                if (indexPath.row == 1)
                {
                    cell.textLabel.text = @"No";
                }
            }
                break;
            case 1:
            {
                if (indexPath.row == 0)
                {
                    if(self.secondSectionIndex != indexPath)
                    {
                        cell.accessoryType = UITableViewCellAccessoryCheckmark;
                    }
                    else
                    {
                        cell.accessoryType = UITableViewCellAccessoryNone;
                    }
                    cell.textLabel.text = @"Easy";
                }
                if (indexPath.row == 1)
                {
                    cell.textLabel.text = @"Medium";
                }
                if (indexPath.row == 2)
                {
                    cell.textLabel.text = @"Hard";
                }
            }
                break;

            default:
                break;
        }
    }

    tableView.backgroundColor = [UIColor clearColor];
    tableView.backgroundView = nil;

    return cell;
}

在我的 didSelectRowAtIndexPath 中,我做了以下操作:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0)
    {
      self.firstSectionIndex = indexPath;
    }
    if (indexPath.section == 1)
    {
       self.secondSectionIndex = indexPath;
    }
    [tableView reloadData];
}

我搜索了要保存的单元格选择状态以供长期参考,在寻找它时,我找到了一些有用的链接here

但是它正在选择多个单元格,并且正在为部分中的所有行应用附件类型复选标记。我不明白出了什么问题。谁能指导我!

提前谢谢大家:)

【问题讨论】:

  • 谷歌搜索而不是谷歌搜索:)
  • 我注意到您从未清除过self.firstSectionIndexself.secondSectionIndex,这不可能?
  • @LithuT.V 已编辑 :),你能帮帮我吗
  • @trojanfoe 你的意思是说设置 firstSectionIndex 和 secondSectionIndex 为零??
  • 是的;在设置一个的代码中,您不需要取消设置另一个吗?

标签: iphone savestate uitableview checkmark


【解决方案1】:

您可以使用下面的代码实现来实现它:-

已编辑

.h 文件

NSMutableArray *firstSelectedCellsArray;
NSMutableArray *secondSelectedCellsArray;
NSMutableArray *ThirdSelectedCellsArray;

在 .m 文件中

    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0)
    {
        NSNumber *rowNumber = [NSNumber numberWithUnsignedInt:indexPath.row];

        UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
        if (selectedCell.accessoryType == UITableViewCellAccessoryNone)
        {
            selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
            if ( [firstSelectedCellsArray containsObject:rowNumber]  )
            {
                [firstSelectedCellsArray removeObject:rowNumber];
            }
            else
            {
                [firstSelectedCellsArray addObject:rowNumber];
            }
        }
        else if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark)
        {
            if ( [firstSelectedCellsArray containsObject:rowNumber]  )
            {
                [firstSelectedCellsArray removeObject:rowNumber];
            }
            else
            {
                [firstSelectedCellsArray addObject:rowNumber];
            }
            selectedCell.accessoryType = UITableViewCellAccessoryNone;
        }
    }

    if (indexPath.section == 1)
    {
        NSNumber *rowNumber = [NSNumber numberWithUnsignedInt:indexPath.row];

        UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
        if (selectedCell.accessoryType == UITableViewCellAccessoryNone)
        {
            selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
            if ( [secondSelectedCellsArray containsObject:rowNumber]  )
            {
                [secondSelectedCellsArray removeObject:rowNumber];
            }
            else
            {
                [secondSelectedCellsArray addObject:rowNumber];
            }
        }
        else if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark)
        {
            if ( [secondSelectedCellsArray containsObject:rowNumber]  )
            {
                [secondSelectedCellsArray removeObject:rowNumber];
            }
            else
            {
                [secondSelectedCellsArray addObject:rowNumber];
            }
            selectedCell.accessoryType = UITableViewCellAccessoryNone;
        }
    }
    if (indexPath.section == 2)
    {
        NSNumber *rowNumber = [NSNumber numberWithUnsignedInt:indexPath.row];

        UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
        if (selectedCell.accessoryType == UITableViewCellAccessoryNone)
        {
            selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
            if ( [ThirdSelectedCellsArray containsObject:rowNumber]  )
            {
                [ThirdSelectedCellsArray removeObject:rowNumber];
            }
            else
            {
                [ThirdSelectedCellsArray addObject:rowNumber];
            }
        }
        else if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark)
        {
            if ( [ThirdSelectedCellsArray containsObject:rowNumber]  )
            {
                [ThirdSelectedCellsArray removeObject:rowNumber];
            }
            else
            {
                [ThirdSelectedCellsArray addObject:rowNumber];
            }
            selectedCell.accessoryType = UITableViewCellAccessoryNone;
        }
    }

}

现在在 cellForRowAtIndexPath 中放一小段代码:-

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }

    if(indexPath.section==0)
    {

        NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];
        if ( [firstSelectedCellsArray containsObject:rowNsNum]  )
        {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
        else
        {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
    }
    if(indexPath.section==1)
    {

        NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];
        if ( [secondSelectedCellsArray containsObject:rowNsNum]  )
        {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
        else
        {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
    }
    if(indexPath.section==2)
    {

        NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];
        if ( [ThirdSelectedCellsArray containsObject:rowNsNum]  )
        {
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        }
        else
        {
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
    }

    return cell;
}

演示链接

http://www.sendspace.com/file/z6oxg2

屏幕截图:

【讨论】:

  • 非常感谢您的回答,但是如何在这两个部分的第一行设置复选标记。另外我在您的代码中观察到,NSIndexPath *checkedIndexPath 没有被使用。
  • 是的,你对它未使用的变量感到抱歉。因此,作为您的检查部分虎钳,您必须将其作为一个部分明智的不同 Selected 数组,例如,您必须检查第一部分,如 if(indexPath.section==0) ,然后将其作为我的答案
  • 对不起,它不起作用,我的意思是复选标记没有被应用,我不知道为什么,这是我的实现代码:pastebin.com/YWsRjAx6
  • 对不起,当我删除 [tableView reloadData] 行时,我可以看到多个复选标记,即选择另一个单元格(行)后前一个单元格复选标记没有消失,更新代码:pastebin.com/XF7V66Hf
  • 我只是在一个 tableview 部分演示中暗示它,请检查我编辑的答案并下载这个演示希望现在你明白了..
【解决方案2】:

我找到了一个精确而完美的解决方案,感谢 Lithu TV 和 Nithin Gobel 指导我正确的方向。不幸的是,他们的解决方案并没有帮助我在每个部分实现 1 个复选标记,但实际上是多个复选标记。所以我想将选定的行保存在用户默认值中,并为最初选择每个部分的第一行,我们声明第一和第二部分索引,分配给索引路径,然后将单元格附件视图分配为复选标记。我们开始吧,让我们先处理与 cellForRowAtIndexPath:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.row,indexPath.section];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
        cell.backgroundColor = [UIColor clearColor];
        cell.textLabel.textColor = [UIColor whiteColor];
        NSUserDefaults *savedState = [NSUserDefaults standardUserDefaults];

        switch (indexPath.section)
        {
            case 0:
            {
                NSNumber *indexNumber = [NSNumber numberWithInteger:indexPath.row];
                if([[savedState objectForKey:@"firstSectionIndex"] isEqual: indexNumber])
                {
                    cell.accessoryType = UITableViewCellAccessoryCheckmark;
                    self.firstSectionIndex = indexPath;
                }

                if (indexPath.row == 0)
                {                    
                    NSObject * checkedCellObject = [savedState objectForKey:@"firstSectionIndex"];
                    if(checkedCellObject == nil)
                    {
                        self.firstSectionIndex = indexPath;
                        cell.accessoryType = UITableViewCellAccessoryCheckmark;
                    }
                    cell.textLabel.text = @"Yes";
                }
                if (indexPath.row == 1)
                {
                    cell.textLabel.text = @"No";
                }
            }
                break;
            case 1:
            {
                NSNumber *indexNumber = [NSNumber numberWithInteger:indexPath.row];
                if([[savedState objectForKey:@"secondSectionIndex"] isEqual: indexNumber])
                {
                    cell.accessoryType = UITableViewCellAccessoryCheckmark;
                    secondSectionIndex = indexPath;
                }

                if (indexPath.row == 0)
                {
                    NSObject * checkedCellObject = [savedState objectForKey:@"secondSectionIndex"];
                    if(checkedCellObject == nil)
                    {
                        cell.accessoryType = UITableViewCellAccessoryCheckmark;
                        secondSectionIndex = indexPath;
                    }
                    cell.textLabel.text = @"Easy";
                }
                if (indexPath.row == 1)
                {
                    cell.textLabel.text = @"Medium";
                }
                if (indexPath.row == 2)
                {
                    cell.textLabel.text = @"Hard";
                }
            }
                break;

            default:
                break;
        }
    }

    tableView.backgroundColor = [UIColor clearColor];
    tableView.backgroundView = nil;

    return cell;
}

请注意在每种情况下,我们正在检查选中状态是否处于保存的用户默认值,如果是 nil,我们检查每个部分的第一个单元格(行),这里我们使用表格视图委托方法,选择行在索引路径:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    if (indexPath.section == 0)
    {
        UITableViewCell *checkCell = [tableView cellForRowAtIndexPath:indexPath];
        if(firstSectionIndex && firstSectionIndex != indexPath)
        {
            UITableViewCell *uncheckCell = [tableView cellForRowAtIndexPath:firstSectionIndex];
            uncheckCell.accessoryType = UITableViewCellAccessoryNone;
        }
        self.firstSectionIndex = indexPath;
        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:firstSectionIndex.row] forKey:@"firstSectionIndex"];
        checkCell.accessoryType = UITableViewCellAccessoryCheckmark;
    }

    if (indexPath.section == 1)
    {
        UITableViewCell *checkCell = [tableView cellForRowAtIndexPath:indexPath];
        if(secondSectionIndex)
        {
            UITableViewCell *unchekCell = [tableView cellForRowAtIndexPath:secondSectionIndex];
            unchekCell.accessoryType = UITableViewCellAccessoryNone;
        }
        self.secondSectionIndex = indexPath;
        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:secondSectionIndex.row] forKey:@"secondSectionIndex"];
        checkCell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
}

就是这样,我们已经成功完成了每个部分的一个复选标记,并将单元格的附件状态保存在用户默认值中以供长期参考。

希望对大家有所帮助,谢谢:)

【讨论】:

    【解决方案3】:

    用于实施复选标记

    1. 为选定的索引保留一个索引数组
    2. 在 cellFor Row 方法中检查当前索引路径是否存在于 选定的索引数组。

    如果为真

        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    

    其他

        cell.accessoryType = UITableViewCellAccessoryNone;
    
    1. 在 didSelect 方法中,如果选中标记。从数组中删除索引也是如此 设置配件类型无
    2. 如果没有附件,则添加复选标记并将索引添加到数组中。

    编辑

    如果您需要的是每次选择单元格时的单一选择,请从数组中删除所有索引并仅添加该索引,然后重新加载表格视图

    【讨论】:

    • 我已经实现了你的建议,但它没有像我预期的那样工作,问题是面临多个复选标记问题,即在选择另一个单元格(行)后,前一个单元格复选标记没有消失,我的实现代码:pastebin.com/XF7V66Hf
    • 我在确实选择行方法中添加了这一行 [self.array removeAllObjects],但它仍然允许多个单元格选择,复选标记:(
    • 等待您的回复,尚未完成任务:(
    • @EshwarChaitanya 那是因为你没有在 did select 方法上重新加载表
    • 抱歉,我在 do select row 方法中调用了重新加载数据
    【解决方案4】:

    我有类似的要求,我需要为每个部分选择一个选项并显示刻度线,我通过简单的步骤实现了相同的目标。 您根本不需要重新加载部分或表格。

    第 1 步:

    为您的模型保留一个哈希表/字典,以记录每个部分类型的选定 IndexPath。

    例子-

    class DeviceSettingModel {
      var indexPathSelectionDict: [DeviceSettingSectionType: IndexPath] = [:]
    }
    
    enum DeviceSettingSectionType: Int {
        case audioDevices
        case videoDevices
        case videoQualities 
    }
    

    第 2 步:

    更新 tableView(didSelectAtRow) 委托中的选择:

    例子-

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
            guard let settingModel = settingModel,
                let type: DeviceSettingSectionType = DeviceSettingSectionType(rawValue: indexPath.section)
            else { return }
    
            // other data and view related updating...
    
    
            // unselect first on the same section.
            if let previousIndex = settingModel.indexPathSelectionDict[type] {
                if let cell = tableView.cellForRow(at: previousIndex) {
                    cell.accessoryType = .none
                }
            }
    
            // update selected indexPath into the model and put a tick mark
            settingModel.indexPathSelectionDict[type] = indexPath
            if let cell = tableView.cellForRow(at: indexPath) {
                cell.accessoryType = .checkmark
            }
    
    }
    

    就是这样,你可以看到下面的效果。

    【讨论】:

      猜你喜欢
      • 2014-09-01
      • 1970-01-01
      • 2017-01-09
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 2013-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多