uisegmentedcontrol дублирование в uitableviewcell
В моем контроллере UITableView у меня есть ячейки, каждая из которых содержит UILabel и UISegmentedController. Всего около 20 ячеек. Пользователь может выбрать UISegmentedControl, чтобы контролировать, содержится ли объект в массиве или нет.
Моя проблема заключается в том, что при прокрутке пользователя UISegmentedControl дублируется и выглядит так, как будто есть несколько вариантов выбора для UISegmentedControl. У меня такое ощущение, что это происходит из-за повторного использования клеток, но, к сожалению, я не очень хорошо понимаю, как использовать клетки.
Я пытался поиграть с:
if(cell == nil){}
но я не уверен, что там должно произойти
В любом случае вот мой код:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"featuresCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSString *feature = [features objectAtIndex:indexPath.row];
UILabel *titleLabel = (UILabel *)[cell viewWithTag:9999];
titleLabel.text = feature;
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc]initWithItems:[NSArray arrayWithObjects:@"Yes", @"No", nil]];
segmentedControl.frame = CGRectMake(215, 17, 85, 28);
[segmentedControl addTarget:self action:@selector(valueChanged:) forControlEvents: UIControlEventValueChanged];
segmentedControl.tag = indexPath.row;
[cell addSubview:segmentedControl];
if ([selectedFeatures containsObject:feature]) {
segmentedControl.selectedSegmentIndex = 0;
}
else{
segmentedControl.selectedSegmentIndex = 1;
}
return cell;
}
Ваша помощь будет принята с благодарностью,
Спасибо за ваше время.
3 ответа
Попробуй это,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"featuresCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSString *feature = [features objectAtIndex:indexPath.row];
UILabel *titleLabel = (UILabel *)[cell viewWithTag:9999];
titleLabel.text = feature;
UISegmentedControl *segmentedControl;
if ([cell.contentView viewWithTag:kSegmentTag]) { //kSegmentTag a tag
segmentedControl = (UISegmentedControl *)[cell viewWithTag:kSegmentTag];
} else {
segmentedControl = [[UISegmentedControl alloc]initWithItems:[NSArray arrayWithObjects:@"Yes", @"No", nil]];
segmentedControl.frame = CGRectMake(215, 17, 85, 28);
[segmentedControl addTarget:self action:@selector(valueChanged:) forControlEvents: UIControlEventValueChanged];
segmentedControl.tag = kSegmentTag;
[cell.contentView addSubview:segmentedControl];
}
if ([selectedFeatures containsObject:feature]) {
segmentedControl.selectedSegmentIndex = 0;
}
else{
segmentedControl.selectedSegmentIndex = 1;
}
return cell;
}
И в valueChanged:
- (IBAction)valueChanged:(id)sender {
UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
CGPoint tablePoint = [segmentedControl convertPoint:segmentedControl.bounds.origin toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:tablePoint];
//here indexpath.row give changed row index
}
Общее правило заключается в том, что каждый подкласс ячейки должен реализовывать - (void)prepareForReuse
чтобы подготовить его к настройке в - (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
, Я думаю, что вы можете решить свою проблему с помощью подклассов UITableViewCell
, создавая каждую ячейку с требуемым UISegmentedControl
и предоставляя способ для настройки сегментированного управления, как требуется.
prepareForReuse
следует сбросить сегментированный элемент управления, чтобы каждый раз при настройке пользовательской ячейки она находилась в известном пустом состоянии.
Преимущество этого подхода состоит в том, что вы не только повторно используете ячейку табличного представления, но также сегментированный элемент управления и любые другие украшения, которые хотите, чтобы ячейка содержала. Кроме того, вы переместили конфигурацию ячейки в объект ячейки.
Вкратце, в методе инициализации подкласса ячейки вы создаете сегментированный элемент управления и добавляете его как подпредставление contentView.
В методе настройки подкласса ячеек вы указываете сегментированные сегменты элемента управления и т. Д.
В клеточном подклассе prepareForReuse
Вы удаляете все эти сегменты и оставляете сегментированный элемент управления в состоянии, готовом к настройке, в следующий раз, когда вы снова используете эту ячейку.
Чтобы пойти еще дальше, начните использовать автоматическое расположение, чтобы расположить сегментированный элемент управления в ячейке, а не использовать набор жестких чисел в кадре. Если вы работаете на одном типе устройства, это замечательно, но как только ваши ячейки будут иметь разные размеры (в виде таблицы на другом устройстве), все будет выглядеть не так хорошо.
cell
никогда не ноль, так что это не поможет вам.
Хитрость заключается в том, чтобы пометить ячейку таким образом, чтобы узнать, был ли сегментированный элемент управления уже добавлен. Лучший способ - использовать тег сегментированного элемента управления. К сожалению, вы, кажется, используете этот тег для каких-то других целей, поэтому вам нужно прекратить это делать:
if (![cell viewWithTag:12345]) {
UISegmentedControl *segmentedControl = // ....;
// ....
segmentedControl.tag = 12345;
[cell.contentView addSubview:segmentedControl];
}
И теперь, вы видите, вам гарантировано, что в ячейке есть ровно один сегментированный элемент управления, и вы можете найти его, вызвав [cell viewWithTag:12345]
,