如何设置此自定义UITableViewCell

时间:2014-08-20 17:14:57

标签: ios uitableview

我接管了一个iOS项目,并且必须将视图列表重构为UITableView。我正在使用Storyboard并且已经将UITableViewCell子类化了。一个子类称为MenuItemCell,它有一个headerLabel,detailLabel和priceLabel,它们是在Storyboard中设置并在MenuItemCell中配置的属性。我可以像这样通过cellForAtIndexPath来操作这些:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
  static NSString *MenuItemCellIdentifier=@"MenuItemCell";
  id dic=self.tmpMenu.listItems[indexPath.row];
  if([dic isKindOfClass:[MenuItem class]]){
    MenuItemCell *cell = [self.menuTV dequeueReusableCellWithIdentifier:MenuItemCellIdentifier];
    MenuItem *menuItem=(MenuItem *)dic;
    cell.menuItem=menuItem;

    cell.headerLabel.text=menuItem.header;
    cell.headerLabel.numberOfLines=0;

    cell.priceLabel.text=menuItem.price;

     // how to handle this custom spotView
     if([menuItem hasInstoreImage]){
        UIView *instoreImageDot=[self circleWithColor:[UIColor redColor] radius:4];
        [cell.spotView addSubview:instoreImageDot];  // ON SCROLLING, this populates to all the different table cells
      }

    return cell;
  }
  return nil;
}

最后一部分是有一个名为spotView的自定义UIView。目前,我通过circleWithColor在我的控制器中的代码中创建这个圆圈并尝试添加到[cell.spotView]但滚动导致它填充在不同的表格单元格上。我怎么设置这个?我已经在我的自定义视图中添加了一个方法,但这也遇到了同样的问题。

thx任何帮助

2 个答案:

答案 0 :(得分:2)

单元格被重用,您需要告诉tableView删除自定义视图

 if([menuItem hasInstoreImage]){
    UIView *instoreImageDot=[self circleWithColor:[UIColor redColor] radius:4];
    [cell.spotView addSubview:instoreImageDot]; 
  }else{
    //remove it if condition is not met
    //or You can add a place holder view instead
  }

答案 1 :(得分:1)

正在发生的事情是iOS在滚动时重复使用单元格,并且一些重用的单元格已经将instoreImageDot视图添加为子视图。

你真的不应该在cellForRowAtIndexPath方法中做布局。它应该只用于使可重复使用的单元出列,然后设置单元的数据。所有布局内容都应该由单元本身处理。

不要在控制器中创建instoreImageDot。在自定义单元格中添加一个方法 - 类似于(用C#编写,但应该很容易翻译):

UpdateCell(MenuItem item, bool hasInstoreIamge)
{
    menuItem = item;
    headerLabel.text = item.header;
    priceLabel.text = item.price;
    headerLabel.numberOfLines=0;

    if (hasInstoreImage)
    {
       // code to add the instoreImageDot as a subview of the cell
    }
}

同样在Custom Cell中,实现prepareForReuse方法并在此方法中,从单元格中删除instoreImageDot视图 - 这样它只能添加一次。

- (void)prepareForReuse {
    if([self.subviews containsObject:instoreImageDot])
    {
       [instoreImageDot removeFromSuperview];
     }

    [super prepareForReuse]; 
}

现在你的cellForRowAtIndexPath方法看起来像:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
  static NSString *MenuItemCellIdentifier=@"MenuItemCell";
  id dic=self.tmpMenu.listItems[indexPath.row];
  if([dic isKindOfClass:[MenuItem class]]){
    MenuItemCell *cell = [self.menuTV dequeueReusableCellWithIdentifier:MenuItemCellIdentifier];
    MenuItem *menuItem=(MenuItem *)dic;

cell.UpdateCell(menuItem, [menuItem hasInstoreImage]);

    return cell;
  }
  return nil;
}