【问题标题】:UISegmentedControl duplicating in UITableViewCellUISegmentedControl 在 UITableViewCell 中重复
【发布时间】:2014-03-17 04:14:15
【问题描述】:

在我的 UITableView 控制器中,我有单元格,每个单元格都包含一个 UILabel 和 UISegmentedController。总共有大约20个细胞。用户可以选择 UISegmentedControl 来控制对象是否包含在数组中。

我的问题是,当用户滚动 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;
}

非常感谢您的帮助,

感谢您的宝贵时间。

【问题讨论】:

  • 将您的代码从NSString *feature 包装到内部,如if(cell == nil) { NSString *feature = ........} return cell;
  • 你在使用故事板吗?
  • @arthan.v 谢谢,但如果我这样做,则不会显示该段,并且标签的文本不会更改以显示该功能。
  • @Akhilrajtr 是的,我正在使用情节提要,但我没有在情节提要中添加 UISegmentedControl,而是将其添加到 cellForRow 中,这样我就可以知道标签值正在添加/删除哪个功能。跨度>
  • 从未向单元格添加任何子视图!将子视图添加到单元格的contentView

标签: ios objective-c uitableview uisegmentedcontrol


【解决方案1】:

cell 永远不会为零,所以这对您没有帮助。

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

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

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

【讨论】:

  • 谢谢马特,您的回答也是正确的,但我将另一个标记为第一个。也感谢cell.ContentView addSubview 的建议!
【解决方案2】:

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

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

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

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

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

在单元格子类prepareForReuse 中,您删除所有这些段,并使分段控件处于准备好配置的状态,以便下次重用该单元格时进行配置。

更进一步,开始使用自动布局将分段控件定位在单元格中,而不是在框架中使用一组硬数字。如果您让他们在一种很棒的设备上工作,但是一旦您的单元格具有不同的尺寸(在不同设备上的表格视图中),事情看起来就不那么好了。

【讨论】:

    【解决方案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
     }
    

    【讨论】:

    • 谢谢,但如果我使用此代码,我会收到错误 'NSInvalidArgumentException', reason: '-[UITableViewCell setSelectedSegmentIndex:]。我之前也遇到过这个错误,我不明白为什么
    • @Shayno 使用kSegmentTag 作为segmentcontrol 的常量标签并尝试。
    • 对不起,我不熟悉 kSegmentTag 是什么...添加时我得到未声明的标识符。
    • @Shayno 你可以看到它here 或者只是使用 8888 或其他值来代替
    • 好的,我现在可以正常工作了,我只需要在代码中更改一件事。与segmentedControl = (UISegmentedControl *)[cell viewWithTag:indexPath.row];。该代码正在查找带有标签indexPath.Row 的其他对象,并在无法更改对象 selectedSegmentIndex 时返回错误。所以我只是把它改成了segmentedControl = (UISegmentedControl *)[cell viewWithTag:8888];
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多