Ios UITableViewCell中的UISegmentedControl复制

Ios UITableViewCell中的UISegmentedControl复制,ios,objective-c,uitableview,uisegmentedcontrol,Ios,Objective C,Uitableview,Uisegmentedcontrol,在我的UITableView控制器中,我有每个包含UILabel和UISegmentedController的单元格。总共大约有20个细胞。用户可以选择UISegmentedControl来控制对象是否包含在数组中 我的问题是,当用户滚动时,UISegmentedControl会重复出现,看起来好像有多个UISegmentedControl选项。我有一种感觉,这是因为细胞正在被重用,但不幸的是,我对细胞的重用没有很好的理解 我一直在尝试玩: if(cell == nil){} 但我不确定那里会

在我的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;
}
非常感谢您的帮助

谢谢您的时间。

试试这个

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

单元格
永远不会为零,因此这对您没有帮助

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

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

现在,您可以看到,您可以保证单元中只有一个分段控件,您可以通过调用
[cell viewWithTag:12345]
找到它。一般规则是每个单元子类都应该实现
-(void)prepareforeuse
,以便在
-(UITableViewCell*)中进行配置cellForRowAtIndexPath:(NSIndexPath*)indexPath
。我认为可以通过子类化
UITableViewCell
,使用所需的
UISegmentedControl
创建每个单元格,并根据需要提供配置分段控件的方法来解决问题

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

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

简单地说,在cell子类init方法中创建分段控件并将其添加为contentView的子视图

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

在cell子类
prepareForReuse
中,删除所有这些段,并将分段控件保持在可供下次重用该单元格时配置的状态


更进一步,开始使用“自动布局”在单元格中定位分段控件,而不是在帧中使用一组硬数字。如果你让那些人在一种很好的设备上工作,但是一旦你的单元格有不同的维度(在不同设备上的表视图中),事情就不会这么好了。

将你的代码从
NSString*feature
包装到里面,比如,
If(cell==nil){NSString*feature=..}返回单元格
您正在使用故事板吗?@arthan.v谢谢,但如果我这样做,则不会显示片段,标签文本也不会更改以显示功能。@Akhilrajtr是的,我正在使用故事板,但我不会在故事板中添加UISegmentedControl,我将它添加到cellForRow中,这样我就可以知道标签值正在添加/删除哪个功能。从未将任何子视图添加到单元格中!将子视图添加到单元格的
contentView
。谢谢,但是如果我使用此代码,我会得到一个错误
“NSInvalidArgumentException”,原因:'-[UITableViewCell setSelectedSegmentIndex:
。我之前也犯了这个错误,我无法理解why@Shayno使用
kSegmentTag
作为segmentcontrol的常量标记并重试。对不起,我不熟悉kSegmentTag是什么。。。添加时,我得到了未声明的标识符。@Shayno您可以看到它,或者只使用8888或其他值来代替它。好的,我现在工作正常,只是需要在代码中更改一件事。使用
segmentedControl=(UISegmentedControl*)[cell viewWithTag:indexPath.row]。代码正在查找标记为
indexPath.Row
的其他对象,并在无法更改selectedSegmentIndex对象时返回错误。所以我把它改成了
segmentedControl=(UISegmentedControl*)[cell-viewWithTag:8888]。谢谢,马特。你的答案也是正确的,但我把另一个标记为第一个。感谢您对cell.ContentView addSubview的建议!