#iphone #objective-c #ios #xcode #uitableview
#iPhone #objective-c #iOS #xcode #uitableview
Вопрос:
У меня есть UITableView, в котором вы можете отметить только 4 ячейки. Если я отмечу определенное количество ячеек, а затем прокручиваю вверх или вниз, он будет отмечать случайные ячейки. Я не понимаю логики, стоящей за этим, потому что единственный метод, который я использую для пометки, — это DidSelectRowAtIndex, который не выполняется (я поставил там точку останова, чтобы проверить ее). Я действительно не знаю, что может быть причиной этого, но вот cellForRowAtIndex:
- (UITableViewCell *) tableView: (UITableView *) tableView
cellForRowAtIndexPath: (NSIndexPath *) indexPath
{
static NSString *cellName = @"PrefsTableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
cellName];
if (cell == nil)
{
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellName] autorelease];
}
NSUInteger row = [indexPath row];
Drink *drink = [drinks objectAtIndex:row];
cell.textLabel.text = drink.name;
cell.detailTextLabel.text = [NSString stringWithFormat:@"%d", drink.caffeine];
[[cell imageView] setImage:drink.image];
return cell;
}
У меня такое чувство, что это как-то связано с этим, но я не могу точно сказать.
Вот как это выглядит до прокрутки:
Это то, что происходит, когда я прокручиваю вверх:
Я не нажимал на этот верхний. Если я снова прокручиваю вниз и вверх, он, скорее всего, не будет отмечен, а другой будет отмечен.
Это может быть важно, поэтому вот метод didSelectRowAtIndexPath:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath: indexPath];
NSLog(@"TESTING");
if ((cell.accessoryType == UITableViewCellAccessoryNone) amp;amp; [[DataContainerSingleton theDataContainerSingleton].favourites count] < 4)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[[DataContainerSingleton theDataContainerSingleton].favourites addObject:[drinks objectAtIndex:indexPath.row]];
NSLog(@"CHECKED %d", [[DataContainerSingleton theDataContainerSingleton].favourites count]);
}
else if (cell.accessoryType == UITableViewCellAccessoryCheckmark)
{
for (int i = 0; i < [[DataContainerSingleton theDataContainerSingleton].favourites count]; i )
{
NSString *drinkName = [[drinks objectAtIndex:indexPath.row] name];
NSString *favName = [[[DataContainerSingleton theDataContainerSingleton].favourites objectAtIndex:i] name];
if ([drinkName isEqualToString: favName])
{
cell.accessoryType = UITableViewCellAccessoryNone;
[[DataContainerSingleton theDataContainerSingleton].favourites removeObjectAtIndex:i];
NSLog(@"UNCHECKED %d", [[DataContainerSingleton theDataContainerSingleton].favourites count]);
}
}
}
}
Комментарии:
1. Изменяете ли вы содержимое вашего tableview динамически? или он загружается только один раз?
2. он изменяется динамически. cellForRowAtIndexPath вызывается автоматически каждый раз, когда вы прокручиваете вверх или вниз, на экране появляется новая ячейка.
Ответ №1:
Вы не сохраняете, какие элементы были отмечены. Вы должны сохранить индексы в массиве и установить галочку cellForRowAtIndexPath:
. Что-то вроде-
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if(![self.tickedIndexPaths containsObject:indexPath]) //tickedIndexPaths is an array
[self.tickedIndexPaths addObject:indexPath];
else
[self.tickedIndexPaths removeObject:indexPath];
}
Затем-
- (UITableViewCell *) tableView: (UITableView *) tableView
cellForRowAtIndexPath: (NSIndexPath *) indexPath
{
static NSString *cellName = @"PrefsTableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
cellName];
if (cell == nil)
{
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellName] autorelease];
}
NSUInteger row = [indexPath row];
Drink *drink = [drinks objectAtIndex:row];
cell.textLabel.text = drink.name;
cell.detailTextLabel.text = [NSString stringWithFormat:@"%d", drink.caffeine];
[[cell imageView] setImage:drink.image];
if([self.tickedIndexPaths containsObject:indexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
Имейте в виду, что из-за повторного использования ячеек последний блок else очень важен.
Комментарии:
1. Я действительно сделал такую проверку. Я прикрепил didSelectRowAtIndexPath .
2. Вы абсолютно правы, когда выбираете
accessoryType
indidSelect...
Однако крайне важно, чтобы выcellFor...
также установили его в соответствии сDataContainerSingleton
. Это связано с тем, что ячейки повторно используются при прокрутке, и вам необходимо повторно синхронизировать внешний вид ячейки с вашим классом модели (DataContainerSingleton).