【问题标题】:How to know if a row in a UITableView has been selected?如何知道 UITableView 中的一行是否已被选中?
【发布时间】:2014-04-15 20:57:56
【问题描述】:

我使用 Apple 的 MultiSelectTableView 作为了解 NSIndexSet 的一种方式。我可以轻松地创建选定的项目并在调试器中读回它们。

我已经尝试了几种方法来在应用程序再次运行时“读取”集合,但我无法弄清楚这一点。因此,如果我选择几行并退出应用程序,下次运行时,选择不会持续。我已经读过这个post 等等,但我只是不明白。

我一直在尝试为此使用NSUserDefaults

NSMutableIndexSet *indicesOfItemsToShow = [NSMutableIndexSet new];

for (NSIndexPath *selectionIndex in selectedRows)
{
    [indicesOfItemsToShow addIndex:selectionIndex.row];
    NSLog(@"selectionIndex.row: %i", selectionIndex.row);
    NSUserDefaults *standardDefaults;
    [standardDefaults setObject:selectionIndex forKey:@"currentState"];
    [standardDefaults synchronize];
}

当我在视图加载时记录调试器时,索引为空。

【问题讨论】:

    标签: ios uitableview nsindexset


    【解决方案1】:

    索引集不是用于表视图中的多行选择的正确工具,因为表视图数据由节和行表示,而索引集包含一维索引。

    如果您希望保持多选,可以使用-[UITableView indexPathsForSelectedRows],它返回一个NSIndexPath 对象数组。然后,您可以保存该数组,并在加载时读取该数组并使用-[UITableView selectRowAtIndexPath:animated:scrollPosition:] 选择正确的单元格。

    另外,您似乎没有正确保存到用户默认值。

    NSUserDefaults *standardDefaults;
    [standardDefaults setObject:selectionIndex forKey:@"currentState"];
    

    应该是

    NSUserDefaults *standardDefaults = [NSUserDefaults standardDefaults];
    [standardDefaults setObject:selectionIndex forKey:@"currentState"];
    

    请注意。根据您在表视图中填充数据的方式,持久化选定行的索引可能是不安全的。跟踪选择了哪个支持对象并使用此信息来选择行会更好。但是对于静态数据,这样就OK了。


    为了进一步解释如何持久化选择,这里有一个例子:

    - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
    {
        NSArray* selectedRows = [tableView indexPathsForSelectedRows];
        NSMutableArray* safeForUserDefaults = [NSMutableArray new];
    
        [selectedRows enumerateObjectsUsingBlock:^(NSIndexPath* indexPath, NSUInteger idx, BOOL *stop)
        {
            NSDictionary* data = @{@"section": @(indexPath.section), @"row": @(indexPath.row)};
            [safeForUserDefaults addObject:data];
        }];
    
        [[NSUserDefaults standardDefaults] setObject:safeForUserDefaults forKey:@"currentState"];
    }
    

    现在,加载:

    - (void)viewDidLoad
    {
        NSArray* previousState = [[NSUserDefaults standardDefaults] objectForKey:@"currentState"];
    
        [previousState enumerateObjectsUsingBlock:^(NSDictionary* data, NSUInteger idx, BOOL *stop)
        {
            [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:[data[@"row"] integerValue] inSection:[data[@"section"] integerValue]] animated:NO scrollPosition:UITableViewScrollPositionNone];
        }];
    }
    

    这是一个非常简单的例子,但应该能让你上路。

    【讨论】:

    • 感谢 Leo,+1。你能告诉我一个如何使用 indexPathForSelectedRows 和 selectRowAtIndexPath 的例子吗?非常感谢
    • @DavidDelMonte 是的,我将使用一些代码编辑答案,向您展示如何保留索引路径。
    • 好的。谢谢狮子座。我会研究这个..和@Anna,感谢您的编辑。
    • @DavidDelMonte 如果您有任何问题,请告诉我。
    • @Leo: 这一行: NSDictionary* data = @{@"section": indexPath.section, @"row": indexPath.row};导致此错误:“NSInteger”(又名“int”)类型的集合元素不是 Objective-C 对象。如果很明显,请告诉我。
    【解决方案2】:

    在您退出应用之前,将 self.storeIndexArray 添加到 NSUserDefaults

    - (void)tableView:(UITableView *)tableView
    didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    [self.storeIndexArray addObject:indexPath];
    
    }
    
    - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    [self.storeIndexArray removeObject:indexPath];
    
    }
    

    【讨论】:

    • 恐怕我还没有得到这个。我在添加对象时记录了 safeForUserDefaults 数组,但是当我在应用程序停止期间检查(进入后台、终止等)时,该数组为空。敲响铃铛?
    猜你喜欢
    • 2017-09-14
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-26
    相关资源
    最近更新 更多