使用 NSMutableArray 中的 BOOL 对象来确定单元格状态

Posted

技术标签:

【中文标题】使用 NSMutableArray 中的 BOOL 对象来确定单元格状态【英文标题】:Using BOOL objects in NSMutableArray to determine cell statuses 【发布时间】:2014-01-21 04:32:13 【问题描述】:

我正在使用NSMutableArray 引用为“stateArray”。 stateArray 需要简单地保存我的单元格的BOOL 值以确定它们是否被选中。这是我的代码..

我的 .h 中的 stateArray:

@property (nonatomic, strong) NSMutableArray *stateArray;

那么 stateArray 不是合成的。它需要在整个数组中填充NO,这样当单元格被选中时,NO 可以替换为 YES。目前,此代码为每个单元格的 stateArray 打印 0(NSLog 位于我的 cellForRowAtIndexPath:if (showCheckmark == YES) 中)。

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

    [[UITableViewCell appearance] setTintColor:[UIColor colorWithHexString:@"#669900"]];

    #define CHECK_NULL_STRING(str) ([str isKindOfClass:[NSNull class]] || !str)?@"":str

    static NSString *CellIdentifier = @"inviteCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    //Customization
    cell.textLabel.highlightedTextColor = [UIColor colorWithHexString:@"#669900"];
    cell.selectionStyle = UITableViewCellSelectionStyleGray;
    cell.backgroundColor = [UIColor blackColor];
    cell.textLabel.textColor = [UIColor whiteColor];
    //Ignore this, it's for UISearchBar 
    BOOL isSearching = tableView != self.tableView;
    NSArray *arrayToUse = (isSearching ? searchResults : contactsObjects);
    id p = arrayToUse[indexPath.row];

    NSString *fName = (__bridge_transfer NSString *)(ABRecordCopyValue((__bridge ABRecordRef)(p), kABPersonSortByFirstName));
    NSString *lName = (__bridge_transfer NSString *)(ABRecordCopyValue((__bridge ABRecordRef)(p), kABPersonSortByLastName));
    cell.textLabel.text = [NSString stringWithFormat:@"%@ %@", CHECK_NULL_STRING(fName), CHECK_NULL_STRING(lName)];

    _stateArray = [NSMutableArray array];
    for (int i = 0 ; i != contactsObjects.count ; i++) [_stateArray addObject:@(NO)];

    BOOL showCheckmark = [[_stateArray objectAtIndex:indexPath.row] boolValue];

    if (showCheckmark == YES)
    
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        NSLog(@"It hit showCheckmark = YES, and stateArray is %@",_stateArray[indexPath.row]);
    
    else
    
        cell.accessoryType = UITableViewCellAccessoryNone;
        NSLog(@"It hit showCheckmark = NO, and stateArray is %@",_stateArray[indexPath.row]);
    

    return cell;


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
    
    id object = contactsObjects[indexPath.row];
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    if (cell.accessoryType == UITableViewCellAccessoryNone)
    
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        [_stateArray replaceObjectAtIndex:indexPath.row withObject:@(YES)];
        [selectedObjects addObject:object];
    
    else
    
        cell.accessoryType = UITableViewCellAccessoryNone;
        [_stateArray replaceObjectAtIndex:indexPath.row withObject:@(NO)];
        [selectedObjects removeObject:object];
    

    //slow-motion selection animation.
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

【问题讨论】:

您可以存储NSNumber,因为您只能在 NSMutableArray 中存储对象,而 bool 是原始数据类型,它具有方法 + (NSNumber *)numberWithBool:(BOOL)value 谁投了反对票,请你改一下。 请取消反对票。 【参考方案1】:

要跟踪所选项目,请使用Dictionary 而不是NSMutableArray,并将indexPath.row 保留为Key,并将选择保留为当前的Value。 p>

除了使用 BOOL's 的数组进行这些操作之外,您还可以更新代码如下。

@property (nonatomic, strong) NSMutableDictionary * selectedRowCollection;

- (void)viewDidLoad

    self.selectedRowCollection = [[NSMutableDictionary alloc] init];


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
    
    id object = contactsObjects[indexPath.row];
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    if (cell.accessoryType == UITableViewCellAccessoryNone)
    
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        [self.selectedRowCollection setObject:@"1" forKey:[NSString stringWithFormat:@"%d",indexPath.row]]; 
    
    else
    
        cell.accessoryType = UITableViewCellAccessoryNone;
        [self.selectedRowCollection removeObjectForKey:[NSString stringWithFormat:@"%d",indexPath.row]];
    

    //slow-motion selection animation.
    [tableView deselectRowAtIndexPath:indexPath animated:YES];


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

    BOOL showCheckmark =  [[self.selectedRowCollection valueForKey:[NSString stringWithFormat:@"%d",indexPath.row]] boolValue];

    if (showCheckmark == YES)
    
        cell.accessoryType = UITableViewCellAccessoryCheckmark;

    
    else
    
        cell.accessoryType = UITableViewCellAccessoryNone;
    

注意:不要忘记在重新加载新的 tableview 数据集时从字典中删除字典项。

【讨论】:

好的,你注意到了我的另一个问题。也就是说,我的 cellForRowAtIndexPath 无法识别单元格和 indexPath.row 是 YES。换句话说,我上面的代码不起作用,它不记得选择了哪些单元格。由于某种原因,[_stateArray replaceObjectAtIndex:indexPath.row withObject:@(YES)]; 无法正常工作 其实很抱歉,你回答了这个问题。这正是我要问的。为什么BOOL 的方式不起作用? 好的,所以当您切换到另一个数据集时,您可以使用完全相同的NSDictionary 来跟踪选择了哪些单元格? @拉姆沙德 @Chisx 你犯了很多错误。 cellForRowAtIndexPath 将适用于每一行(这意味着如果您的表格视图中有 20 行,它会触发 20 次)。您每次都在此委托中分配数组。所以你会立即丢失数据并为 thr 数组创建新内存。所以数组内的所有项目都将是“否”。就是这样 当您切换到另一个数据集时,您必须从字典中删除字典项。调用 [self.selectedRowCollection removeAllObjects];在重新加载表之前。如果您要更新表格内的任何现有数据(如文本、图像等),请不要执行任何操作。【参考方案2】:

BOOL 值被 NSNumber 包裹,这就是为什么你得到 0:

_stateArray = [NSMutableArray array];
for (int i = 0 ; i != contactsObjects.count ; i++) [_stateArray addObject:@(NO)];

BOOL showCheckmark = [[_stateArray objectAtIndex:indexPath.row] boolValue];

if (showCheckmark == YES)

    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    NSLog(@"It hit showCheckmark = YES, and stateArray is %@",[[_stateArray objectAtIndex:indexPath.row] boolValue] ? @"YES" : @"NO");

else

    cell.accessoryType = UITableViewCellAccessoryNone;
    NSLog(@"It hit showCheckmark = NO, and stateArray is %@",[[_stateArray objectAtIndex:indexPath.row] boolValue] ? @"YES" : @"NO");

BOOL 不是对象,因此您不能使用%@ 格式说明符。你需要手动处理这个

【讨论】:

【参考方案3】:

试试这个,

更新您的循环以填充_stateArray

for (int i = 0 ; i != contactsObjects.count ; i++) 

     [_stateArray addObject:[NSNumber numberWithBool:NO]];

【讨论】:

以上是关于使用 NSMutableArray 中的 BOOL 对象来确定单元格状态的主要内容,如果未能解决你的问题,请参考以下文章

无法将“NSMutableArray”类型的值转换为预期的参数类型“[SKTexture]”

NSMutableArray enumerateObjectsUsingBlock 不像 Apple 所说的那样同步

第32月第12天 block stop

使用 NSMutableArray 中的数据填充 UITableView

XCode 5 中的错误接收器类型“无效”错误

与修改 NSMutablearray 中的值相关的问题