UITableView cellForRowAtIndexPath параметр аксессуара галочки действует странно
Установка: у меня есть свойство с именем "_itemListArray(ivar)", для которого задан список "Item(NSString itemName, NSString itemPrice)". Я заполняю UITableView этими элементами, и пользователь может выбрать несколько строк, отображая галочку в этой строке. IndexPath проверяемой ячейки сохраняется в IVAR(_selectedItemRows). Если пользователь снова выбирает строку, для аксессуара галочки устанавливается значение none, а indexPath удаляется из IVAR(_selectedItemRows). В "cellForRowAtIndexPath" я проверяю находящийся в очереди indexPath для всех indexPaths в _selectedItemRows(массив indexPaths проверенных ячеек). Если путь индекса находится в массиве, я проверяю ячейку в очереди, если нет, я снимаю галочку.
Проблема: Аксессуар галочки установлен правильно (didSelectRowAtIndexPath), но когда я прокручиваю, он действует напуганно. Например, если я проверяю первую ячейку, затем прокручиваю вниз, затем прокручиваю назад до первой ячейки, nslogs проверил, что моя программа знает, что нужно проверять ячейку, но, похоже, это не так.
Кроме того, если я проверяю 2 или более ячеек, прокручиваю вниз, а затем прокручиваю назад вверх, обычно проверяется только последняя ячейка.
Код:
@implementation
@synthesize itemListArray = _itemListArray;
@synthesize selectedItemRows = _selectedItemRows;
-(void)setItemListArray:(NSArray *)itemListArray
{
_itemListArray = itemListArray;
[_propTableView reloadData];
}
- (void)viewDidLoad
{
[super viewDidLoad];
_selectedItemRows = [[NSMutableArray alloc] init];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [_itemListArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Item Selected Reuse"; //Identifier of prototype cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (nil == cell) { //If somethong goes wrong, all hell breaks loose.
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
NSLog(@"%s", __PRETTY_FUNCTION__);
}
// Configure the cell...
Item *curItem = [_itemListArray objectAtIndex:indexPath.row]; //Get the model information at row location.
cell.textLabel.text = curItem.itemName; //Set the name of the item in title field
cell.detailTextLabel.text = curItem.itemPrice; //Set the price of the item in the detail field.
for(NSIndexPath * elem in _selectedItemRows)
{ //Enumerate through checked cells
//NSIndexPath *ip = [_selectedItemRows objectAtIndex:x];
if ([indexPath compare:elem] == NSOrderedSame) { //If the current cell index path ='s any index path in the array of checked cells, check this cell.
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
return cell;
}
//pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; //Get cell clicked on.
if(cell.accessoryType == UITableViewCellAccessoryNone){ //When selected, if the cell is checked, uncheck it.
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[_selectedItemRows addObject:indexPath]; //Add the index path of checked cell into array to use later for comparisons
} else {
if(cell.accessoryType == UITableViewCellAccessoryCheckmark){ //If the cell is checked, uncheck it when clicked on
cell.accessoryType = UITableViewCellAccessoryNone;
[_selectedItemRows removeObject:indexPath]; //Remove that index path of unchecked cell from index array
}
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];//Deselect row after done.
}
@end
//Other code left out for brevity sake
1 ответ
У вас есть логическая ошибка в вашем коде. Подумайте о том, что происходит в этом фрагменте кода:
for(NSIndexPath * elem in _selectedItemRows)
{ //Enumerate through checked cells
//NSIndexPath *ip = [_selectedItemRows objectAtIndex:x];
if ([indexPath compare:elem] == NSOrderedSame) { //If the current cell index path ='s any index path in the array of checked cells, check this cell.
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
Если путь индекса для текущей строки не окажется последним в _selectedItemRows
ячейка будет очищена. Он установит галочку, когда найдет его в _selectedItemRows
и затем сбросьте это, поскольку это продолжает искать. Вместо этого вы хотите заменить это чем-то вроде следующего:
cell.accessoryType = UITableViewCellAccessoryNone;
for(NSIndexPath * elem in _selectedItemRows)
{ //Enumerate through checked cells
//NSIndexPath *ip = [_selectedItemRows objectAtIndex:x];
if ([indexPath compare:elem] == NSOrderedSame) { //If the current cell index path ='s any index path in the array of checked cells, check this cell.
cell.accessoryType = UITableViewCellAccessoryCheckmark;
break;
}
}