在UITableView中为每个部分设置一个复选标记并保存其状态

时间:2013-05-14 07:08:44

标签: iphone savestate uitableview checkmark

花了几个小时,没有用。我不明白我是否在搜索(谷歌搜索)方面没有效果,或者对此问题的解答较少,或者在实施专家答案时我可能犯了一些错误!

我知道有关于为一行设置附件类型复选标记有几个问题,而对于部分中的其他行没有设置任何问题,请跟踪帖子herethere

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

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

但它正在选择多个单元格并且附件类型复选标记正在应用于部分中的所有行。我不明白什么是错的。任何人都可以指导我!!

提前感谢所有人:)

4 个答案:

答案 0 :(得分:3)

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

<强> EDITED

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

DEMO LINK

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

<强>截图:

enter image description here

答案 1 :(得分:2)

我找到了一个精确而完美的解决方案,感谢Lithu TV和Nithin Gobel指导我朝着正确的方向前进。不幸的是,他们的解决方案并没有帮助我实现每个部分1个复选标记,但实际上是多个复选标记。所以我想在用户默认值中保存选定的行,并且最初选择每个部分的第一行,我们声明第一和第二部分索引,分配到索引路径,然后将单元附件视图指定为复选标记。我们去,让我们第一次交易with 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;
}

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

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

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

希望这对某人有所帮助,谢谢:)

答案 2 :(得分:1)

用于实施复选标记

  1. 保留所选索引的索引数组
  2. 在cellFor Row方法中检查当前索引路径是否存在 选定的索引数组。
  3. 如果是真的

        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    

    否则

        cell.accessoryType = UITableViewCellAccessoryNone;
    
    1. 在didSelect方法中,如果checkmarked.Remove索引也来自数组 设置附件类型无
    2. 如果附件none,则添加复选标记并将索引添加到数组中。
    3. 编辑

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

答案 3 :(得分:0)

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

第 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
        }

}

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

Select each device configuration section wise