Using BOOL objects in NSMutableArray to determine cell statuses

帅比萌擦擦* 提交于 2019-12-08 12:39:24

问题


I'm using an NSMutableArray referenced as 'stateArray'. stateArray needs to simply hold the BOOL value for my cells to determine whether or not they are selected. here's my code..

stateArray in my .h:

@property (nonatomic, strong) NSMutableArray *stateArray;

Then stateArray is not synthesized. It needs to be filled with NO throughout the array, so that when the cell becomes selected, NO can be replaced by YES. Currently this code is printing 0's for stateArray for every cell(the NSLog is in the if (showCheckmark == YES) from my cellForRowAtIndexPath:).

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

回答1:


To keep track on selected items, use a Dictionary instead of NSMutableArray and keep the indexPath.row as Key and selection as curresponding Value.

Also instead of doing these operations with array of BOOL's , you can update the code as below.

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

Note: Don't forget remove the dictionary items from dictionary while reloading a new tableview dataset.




回答2:


BOOL values are wrapped with NSNumber, that's why you get 0's:

_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 is not object, so you cannot use the %@ format specifier. You need to handle this manually




回答3:


Try this,

Update your loop to populate _stateArray by

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

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


来源:https://stackoverflow.com/questions/21249219/using-bool-objects-in-nsmutablearray-to-determine-cell-statuses

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!