使用 NSUserDefaults 持续保持 UITableView 选定单元格的 UIAccessoryType

Posted

技术标签:

【中文标题】使用 NSUserDefaults 持续保持 UITableView 选定单元格的 UIAccessoryType【英文标题】:Persistently keeping a UITableView selected cell's UIAccessoryType with NSUserDefaults 【发布时间】:2014-03-31 21:55:12 【问题描述】:

关于这个主题有很多问题,我已经用各种选项尝试了几个小时,但我需要一些真正的帮助。

主要前提是:我有一个Tab Bar controller,有两个标签;第一个是Timeline,第二个是In-App Settings(都是table view controllers)。在In-App settings 中,当我选择“键盘”时,我被转到另一个表格视图,其中包含两个静态单元格:浅色和深色。

我想要实现的是:当我点击其中一个单元格时,它会在该cell 上放置一个checkmark accessory 视图。

使用NSUserDefaults,我想维护选定的单元格并将该单元格的附件类型设置为下次视图重新加载时的复选标记。

我遵循了这个问题的选择答案,而我的代码允许我选择浅色或深色单元格;它永远不会在重新加载之间保持这一点。

这是我的cellForRowAtIndexPath

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];    
    self.selectedKeyboardCell = [[NSUserDefaults standardUserDefaults] objectForKey:@"Selected"];

    NSLog(@"The selected keyboard is %@", self.selectedKeyboardCell);

    if([self.checkedIndexPath isEqual:indexPath])
    
        NSLog(@"Loaded");
        cell.accessoryType = UITableViewCellAccessoryCheckmark;

    
    else
    
        NSLog(@"Not Loaded");

        cell.accessoryType = UITableViewCellAccessoryNone;
        /*if ([self.selectedKeyboardCell isEqualToString:@"Light"])
        
            NSLog(@"P");
            if (indexPath.row == 0)
            
                NSLog(@"Q");
                cell.accessoryType = UITableViewCellAccessoryCheckmark;
            
            cell.accessoryType = UITableViewCellAccessoryNone;

        
        else
        
            NSLog(@"R");
            if (indexPath.row == 1)
            
                NSLog(@"Z");
                cell.accessoryType = UITableViewCellAccessoryCheckmark;
            
            cell.accessoryType = UITableViewCellAccessoryNone;
*/

    

我的didSelectRowAtIndexPath 是:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    // Uncheck the previous checked row
    if(self.checkedIndexPath)
    
        UITableViewCell* uncheckCell = [tableView
                                        cellForRowAtIndexPath:self.checkedIndexPath];
        uncheckCell.accessoryType = UITableViewCellAccessoryNone;
    
    UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    self.checkedIndexPath = indexPath;

    self.selectedKeyboardCell = cell.textLabel.text;

    [[NSUserDefaults standardUserDefaults] setObject:self.selectedKeyboardCell forKey:@"Selected"];

    self.selectedKeyboardTheme = cell.textLabel.text;

    [tableView deselectRowAtIndexPath:indexPath animated:YES];


    [[NSUserDefaults standardUserDefaults] setObject:self.selectedKeyboardTheme forKey:@"Keyboard"];
    [[NSUserDefaults standardUserDefaults] synchronize];

我的viewWillAppear 中有一个[self.keyboardTableView reloadData];

我已经注释掉了一些我一直在尝试的代码,但是无论我阅读了多少帖子,我都无法在这里找到解决方案。

这个问题谈到将代码转移到 viewWillAppear 但我不知道他在说什么代码:Ho to refresh view and tableview, and checkmark a default setting cell on load?

问题:我想在表格视图中选择一个单元格,并在下次(以及每次加载此视图时)使用复选标记附件类型选择该单元格。这是一个静态表格,文本只会说 Light 或 Dark。

cellForRowAtIndexPath 中,self.selectedKeyboardCell 准确地告诉我是浅色还是深色,这取决于在加载视图之前选择了哪个单元格。但是,我怎么说“如果亮,在第一个单元格上设置复选标记并从第二个单元格中删除复选标记,如果是暗,在第二个单元格上设置复选标记并从第一个单元格中删除复选标记”。

更新: 为清楚起见,我可以选择 Light 或 Dark 静态表格视图单元格,无论我选择哪个单元格,复选标记都会正确显示。问题是当我转到另一个视图并返回此视图时,先前选择的单元格不显示。我将 selectedCell 的 textLabel 保存到 NSUserDefaults 并在 NSLog 中,它显示了所选单元格的文本,但没有显示所选单元格上的复选标记。

更新二: 为了在应用程序第一次运行时将默认选定的单元格设置为 Light,我在 cellForRowAtIndexPath 中执行了以下操作:

if (!self.selectedKeyboardCell)

    self.checkedIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    cell.accessoryType = UITableViewCellAccessoryCheckmark;

对此的任何指导将不胜感激。

【问题讨论】:

【参考方案1】:

老实说,您的代码有点令人困惑,如果您多说一些实际有效的代码,它会有所帮助。但是:

viewWillAppear 中你应该只设置self.checkedIndexPath:

if ([self.selectedKeyboardCell isEqualToString:@"Light"])

   self.checkedIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
else
   self.checkedIndexPath = [NSIndexPath indexPathForRow:1 inSection:0];

[self.keyboardTableView reloadData];

对吗?

【讨论】:

亲爱的@Nils - 对于我的问题不够清晰,我深表歉意,但您的回答完美地完成了工作。我会更新我的问题,以确保那里清楚。不过,我确实有一个快速跟进的问题。如果我卸载并重新安装我的应用程序,带有复选标记的默认单元格是“暗”;我希望它是“Light”单元格(即 indexPathForRow:0。我尝试将其添加到情节提要中,将复选标记添加到 Light Cell 但它没有任何区别。我将如何(以及在​​哪里)设置默认选择状态(应用程序第一次运行)到 Light? 实际上,我刚刚开始工作,并使用更新二更新了我的问题以反映已完成的代码。我真的非常感谢@Nils - 你为我节省了几个小时,你帮助我完成了这项工作。对此,我真的非常感激。如果可以的话,我会投票给你两次。

以上是关于使用 NSUserDefaults 持续保持 UITableView 选定单元格的 UIAccessoryType的主要内容,如果未能解决你的问题,请参考以下文章

XCTest:在 UI 测试类的 NSUserdefaults 中未检索到值

XCTest:UI测试类中的NSUserdefaults中未检索到的值

ios应用程序使用nsuserdefaults持久保存数据?

在模拟器上卸载应用程序后,NSUserDefaults未清除

使用 NSUserDefaults 如何在应用程序首次运行之前保存密钥

通过 Testflight 安装新版本时,NSUserDefaults 是不是仍然存在?