UISegmentedControl在UITableViewCell中重复

时间:2014-03-17 04:14:15

标签: ios objective-c uitableview uisegmentedcontrol

在我的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 个答案:

答案 0 :(得分:1)

cell永远不会为零,所以不会帮助你。

诀窍是以某种方式标记单元格,以便知道是否已经添加了分段控件。最好的方法是使用分段控件的标签。不幸的是,您似乎将标签用于其他目的,因此您需要停止这样做:

if (![cell viewWithTag:12345]) {
     UISegmentedControl *segmentedControl = // ....;
     // ....
    segmentedControl.tag = 12345;
    [cell.contentView addSubview:segmentedControl];
}

现在,您可以看到,您可以确保单元格中只有一个分段控件,您可以通过调用[cell viewWithTag:12345]找到它。

答案 1 :(得分:1)

一般规则是每个单元子类应实现- (void)prepareForReuse,以便为- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath中的配置做好准备。我认为您可以通过继承UITableViewCell,使用所需的UISegmentedControl创建每个单元格,并提供一种根据需要配置分段控件的方法来解决您的问题。

prepareForReuse应重置分段控件,以便每次配置自定义单元格时,它都处于已知的空状态。

这种方法的优点在于,您不仅可以重复使用表格视图单元格,还可以重用分段控件以及您希望单元格包含的任何其他装饰。此外,您已将单元格的配置移动到单元格对象中。

简而言之,在单元子类init方法中,您可以创建分段控件并将其添加为contentView的子视图。

在单元子类配置方法中,您可以设置分段控件的段等。

在单元子类prepareForReuse中,删除所有这些段,并在下次重用该单元时将分段控件保留在准备配置的状态。

更进一步,开始使用自动布局将分段控件放置在单元格中,而不是使用框架中的一组硬编号。如果你让那些工作在一种设备上的人很好但是只要你的单元格具有不同的尺寸(在不同设备的表格视图中),事情就不会那么好。

答案 2 :(得分:0)

试试这个,

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