【问题标题】:custom UITableViewCell, a UIView that holds two subviews, and scrolling自定义 UITableViewCell,一个 UIView 包含两个子视图,并且可以滚动
【发布时间】:2015-02-05 05:57:12
【问题描述】:

我有一个自定义 UITableViewCell,它有一个名为 updateCell 的方法。它添加了一个 spotView,它只是一个 UIView,并且 self.spotView 有几个子视图。

问题是,当我滚动时,spotView 会正常启动,但是当您滚动时,它会填满这些子视图和不准确的信息。我该如何解决这个问题?

我已经尝试在我的自定义 UITableViewCell 中使用 prepareForReuse 并尝试删除 spotview 的子视图,但这也不起作用。

我有但有点困惑我需要什么才能使其正常工作。我看到我可以将 uilabel's 设置为 nil 以准备重用,这似乎可行,但这些 UIViews 似乎挂起:

-(void)updateCell:(MenuItem *)item
{
    self.spotView =[[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 10.0f, 10.0f)];
    [self.contentView addSubview:self.spotView];


    [self renderHeader:menuItem.header];
    [self renderDetail:menuItem.detail];
    [self renderMeta:menuItem];
    ...
}

- (void)renderMeta:(MenuItem *)menuItem{
  if([self.spotView.subviews count]>0){
    NSLog(@"THERE ARE subviews in spotView in renderMeta for %@", menuItem.header);
  }else{
    NSLog(@"NO subviews in spotView in renderMeta for %@", menuItem.header);
  }


  for (UIView* view in [self.spotView subviews])
  {
    NSLog(@"!!!about to remove subviews here!!!");
        [view removeFromSuperview]; // <- not working
  }


  if([menuItem hasInstoreImage] || [menuItem hasTastingNotes]){
    if([menuItem hasInstoreImage]){
      UIView *instoreImageDot=[self circleWithColor:[UIColor redColor] radius:4];
      NSLog(@"adding instoreImageDot in renderMeta");
      [self.spotView addSubview:instoreImageDot];
    }else{
      NSLog(@"no instoreImageDot in renderMeta");
    }

编辑#1

玩弄这个,我发现试图操纵自定义 UITableViewCell 中的视图是一个很大的不可预测的问题。我在代码中完成了所有自定义 UITableViewCell,因为我将在公司内部作为 Cocoapod 分发。 DID 的工作是在 ViewController 中操作单元格,具体如下:

// Does not work on iOS below 6.0
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
   if([cell isKindOfClass:[MenuItemCell class]]){
     NSLog(@"A MenuItem Class");
     MenuItemCell *miCell=(MenuItemCell *)cell;
     [miCell.spotView removeFromSuperview];
   }
}

编辑#2

updateCell 的调用位置/方式(略为删减部分代码):

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
  [self.menuTV registerClass:[MenuItemCell class]forCellReuseIdentifier:@"MenuItemCell"]; 

  static NSString *MenuItemCellIdentifier=@"MenuItemCell";

  id dic=self.menu.listItems[indexPath.row];

  if([dic isKindOfClass:[EMBERSMenuItem class]]){
    //MenuItemCell *cell = [self.menuTV dequeueReusableCellWithIdentifier:MenuItemCellIdentifier];
    MenuItemCell *cell = [self.menuTV dequeueReusableCellWithIdentifier:MenuItemCellIdentifier  forIndexPath:indexPath];

    //MenuItem *menuItem=(MenuItem *)dic;
    MenuItem *menuItem=(MenuItem *)dic;

    cell.menuItem=menuItem; // <- probably shouldn't have this
    [cell updateCell:menuItem];

  }else{

【问题讨论】:

  • 对我来说看起来不错。当您运行此代码时,您会看到哪些 cmets?它是否点击了“删除子视图”?
  • 您还说 -updateCell: “添加了一个 spotView”,但代码中没有显示。它真的添加了一个视图,还是在调用 -updateCell: 方法之前,spotView 已经存在?
  • 你能上传一张单元格翻转的图像吗?
  • 什么时候调用updateCell方法?
  • 所以我编辑了问题以包括我添加到 contentView 的位置,并且还找到了一个半解决方案,但它需要在调用 updateCell 的 ViewController 中进行操作

标签: ios uitableview


【解决方案1】:

您应该在单元格的init 方法中将子视图添加到单元格中。否则,如果您在每次渲染单元格时添加子视图,您的单元格将最终拥有与渲染发生时一样多的子视图。

举个例子:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        [self.contentView addSubview:mySubview];
    }
}

然后你可以有一个配置方法来注入你的单元格的数据:

- (void)configureCellWithData:(id)data {
    self.mySubview.setText(data.text);
}

【讨论】:

  • thx amb,嗯...让我重新测试一下,因为我最初就是这样做的。我开始遇到麻烦的地方是这些子视图会根据内容动态调整大小。应该以这种方式重置框架吗?
  • 您始终可以实现layoutSubviews 来计算您的单元格内容大小。
  • thx amb - 当你离开你的其他评论时必须离开;让我更新我的代码,看看是否能解决问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多