使用 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 所说的那样同步