在 UITableViewCell 中动态创建时,UIButton 在 UITableView 上显示多次

Posted

技术标签:

【中文标题】在 UITableViewCell 中动态创建时,UIButton 在 UITableView 上显示多次【英文标题】:UIButton showing multiple times on UITableView when created dynamically in UITableViewCell 【发布时间】:2012-09-03 17:38:40 【问题描述】:

在尝试了各种选项并阅读了关于 SO 的众多答案之后,我发布了这个问题,希望有人可以提供一些见解或解决这个问题:

ios5.1、XCode 4.4.1、故事板、ARC

我有一个“分组”表格视图,每个单元格都包含一堆标签、图像和按钮。标签之一,Description 标签,它的文本可以大也可以小,这意味着如果文本很大,我必须相应地增加标签的大小并相应地放置下面的按钮。我能够做到这一切,但问题是当我滚动经过第一个单元格时按钮会出现两次,并在滚动时不断重复。

这是代码,我所做的只是根据文本计算标签的高度,调整标签的大小,然后将 3 个按钮相应地放置在描述标签下方。

下面的代码仅用于一个按钮,但这应该可以让您了解我在做什么。我曾尝试在自定义单元格类中的“willDisplayCell”中做类似的事情,但当我在表格视图中向下滚动时,3 个按钮仍然重复。请参考截图,前三个按钮甚至不应该显示。

我注意到前 3 个按钮的位置与忽略 sizeIncrement 的位置相同,即“359.0f + sizeIncrement +20”减去“sizeIncrement”,“sizeIncrement”=描述的高度计算后的标签

我也注意到如果我这样做了

float y = 359.0f + 20;

而不是这个

float y = 359.0f + sizeIncrement +20;

Buttons的重复问题消失了。

P.S:我知道这不是最好的代码,但我一直在尝试很多东西来解决这个问题,所以现在没有考虑最佳实践等。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

 static NSString *CellIdentifier = @"tipsid";

 TipsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
 if (cell == nil)
 
     cell = [[TipsCell alloc]
             initWithStyle:UITableViewCellStyleDefault
             reuseIdentifier:CellIdentifier];
 

 id tip = [_tips objectAtIndex: [indexPath section]];

 NSDictionary *tipForIndex = [_tips objectAtIndex: [indexPath section]];
 float sizeIncrement = [Utility getLabelHeightForText:[tipForIndex objectForKey:@"tipDescripion"]
                                            withWidth:285.0f
                                             withFont:[UIFont systemFontOfSize:14.0f]];

 // Here I Resize the Label, code below to create a button and position accordingly.

 float y = 359.0f + sizeIncrement +20;

 UIButton *likeButton = [[UIButton alloc] initWithFrame:CGRectMake(10, y, 80, 26)];
 likeButton.tag = [indexPath section];     

 // add targets and actions
 [likeButton addTarget:self action:@selector(likebuttonClicked:) forControlEvents:UIControlEventTouchUpInside];
 [likeButton setBackgroundImage:[UIImage imageNamed:@"likebutton.png"] forState:UIControlStateNormal];

 [likeButton setImage:[UIImage imageNamed:@"likedButton.png"] forState:UIControlStateSelected];

 // add to a view
 [cell.contentView addSubview:likeButton];

.....类似地创建2个其他按钮

【问题讨论】:

【参考方案1】:

您应该将按钮创建移动到if (cell == nil) 运算符中:

if (cell == nil)

   cell = [[TipsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

   // like button
   float y = 359.0f + sizeIncrement +20;

   UIButton *likeButton = [[UIButton alloc] initWithFrame:CGRectMake(10, y, 80, 26)];
   likeButton.tag = LIKE_BUTTON_TAG_UNIQUE_IN_CONTENT_VIEW; // <<<<<<<<<<----------------     

   // add targets and actions
   [likeButton addTarget:self action:@selector(likebuttonClicked:) forControlEvents:UIControlEventTouchUpInside];
   [likeButton setBackgroundImage:[UIImage imageNamed:@"likebutton.png"] forState:UIControlStateNormal];

   [likeButton setImage:[UIImage imageNamed:@"likedButton.png"] forState:UIControlStateSelected];

   // add to a view
   [cell.contentView addSubview:likeButton];

   // other buttons


// and here you can adjust button positions
UIButton *likeButton = [self.contentView viewWithIndex:LIKE_BUTTON_TAG_UNIQUE_IN_CONTENT_VIEW];

【讨论】:

Nekto,感谢您的回答。我现在没有我的开发机器,所以还没有尝试过你的建议,不过我有一个问题,通常 cell==nil 返回 false 因为下面的代码重用了一个已经实例化的单元格“[tableView dequeueReusableCellWithIdentifier:CellIdentifier] ;",那么如果条件有帮助,如何将代码移动到里面? 如果您要重用已经拥有这些按钮的单元格,为什么还需要创建新按钮? 我不确定我是否完全理解你的问题,但是在设计模式(故事板)中单元格中没有按钮,我需要动态创建按钮并将它们添加到单元格中的描述标签下方,如图所示编码。我尝试了您的建议,但就像我提到的那样,它永远不会进入 if 条件,因此永远不会创建按钮。

以上是关于在 UITableViewCell 中动态创建时,UIButton 在 UITableView 上显示多次的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 中异步向 UITableViewCell 添加视图?

使用 addSubview 动态添加 UITextField 的 UITableViewCell - 如何在键盘上“返回”时获取 UITextField 值

使用发件人标签在 UIbutton 单击事件时更新 UITableViewCell 的标签

Autolayout - 当一个视图具有动态高度时,在 UITableViewCell 中垂直居中两个视图

如何在自动布局中使用 UITableViewCell 的动态高度并在底部视图隐藏时将其他视图向上移动?

自定义 UITableViewCell 创建了两次......让我发疯