UITableViewCell 不显示文本
我有一个小应用程序,列出了数据库中的一堆项目。如果您单击其中一项,应用程序会切换到一个新视图,向您显示该特定项目的所有信息。由于显示的信息量是动态的,因此我通过将第二个视图设为 UITableView 并根据显示的特定对象的需要设置每行的大小来实现此目的。这通常工作得很好,但其中一个项目有一个显示最后一个项目的文本墙。当我尝试查看有关此特定对象的信息时,它不会在文本墙应在的位置显示任何内容。
在调试时,我可以告诉用于确定单元格和标签所需大小的文本是正确的。看起来它正确地确定了大小(它给我的单元格高度为 21298,标签高度为 21294),我可以向下滚动到看起来相当大的空标签。然而,显示有点乱,几乎就像屏幕正在刷新一样。视图顶部的文本从开始的位置一直到屏幕顶部,并且右侧的滚动条也无法正确重新绘制。
有人见过这样的事情吗?
抱歉,无法发布我的屏幕截图,因为我没有足够的代表
编辑:找出答案。一旦过了最短时间,我会将其作为答案发布。
如果其他人遇到这个问题,我想出了一个解决方法。
经过一番挖掘后,我发现当源字符串长度达到 41,000 左右时,它开始导致此绘图错误。因此,我将超过 30,000 个以上的字符串拆分,并向表中添加了多行。现在它显示整个文本墙。
代码:
#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 320.0f
#define CELL_CONTENT_MARGIN 2.0f
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//static NSString *CellIdentifier = @"Cell";
NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d", [indexPath row]];
UILabel *label = nil;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setLineBreakMode:UILineBreakModeWordWrap];
[label setMinimumFontSize:10.0];
[label setNumberOfLines:0];
[label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
[label setTag:1];
if ([indexPath row] == 1 || [indexPath row] == 2)
{
[label setTextColor:[UIColor redColor]];
}
else if ([indexPath row] == 3)
{
[label setTextColor:[UIColor colorWithRed:0.0f green:150.f/255.f blue:30.f/255.f alpha:1.0f]];
}
else if ([indexPath row] == 5)
{
[label setTextColor:[UIColor colorWithRed:155.f/255.f green:145.f/255.f blue:0.0f alpha:1.0f]];
}
[[cell contentView] addSubview:label];
}
NSString *text = [cardInfo objectAtIndex:[indexPath row]];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN *2), 20000000000000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
if (!label)
{
label = (UILabel *)[cell.contentView viewWithTag:1];
}
[label setText:text];
[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN *2), MAX(size.height, 30.0f))];
// Configure the cell...
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *text = [cardInfo objectAtIndex:[indexPath row]];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN *2), 20000000000000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 30.0f);
return height + (CELL_CONTENT_MARGIN * 2);
}
I have a small app that lists a bunch of items in a database. If you click one of the items, the app switches to a new view that shows you all of the information on that particular item. Since the amount of information shown is dynamic, I do this by making the second view a UITableView and setting up the size of each row as needed for the particular object being shown. This normally works fine, but one of the items has a wall of text for the last item shown. When I try to view the information on this particular object, it doesn't display anything where the wall of text should be.
While dubugging I can tell the text that is being used to determine the size the cell and label need to be is correct. It seems like it is determining a size correctly (it gives me a height of 21298 for the cell and 21294 for the label) and I can scroll down into what appears to be a rather large empty label. However, the display is a bit messed up, almost as if the screen was refreshing. The text at the top of the view stutters from where it started all the way to the top of the screen and the scroll bar on the right side doesn't repaint correctly either.
Anyone seen something like this before?
Sorry, can't post the screenshots I have since I don't have enough rep
EDIT: Figured out an answer. I will post it as an answer once the minimum time passes.
I figured out a workaround, if anyone else runs into this.
After some digging around, I found out that when the source string length gets to around 41,000, it starts causing this drawing error. So I split up any string over ~30,000 and added multiple rows to the table. It now displays the entire wall of text.
Code:
#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 320.0f
#define CELL_CONTENT_MARGIN 2.0f
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//static NSString *CellIdentifier = @"Cell";
NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d", [indexPath row]];
UILabel *label = nil;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setLineBreakMode:UILineBreakModeWordWrap];
[label setMinimumFontSize:10.0];
[label setNumberOfLines:0];
[label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
[label setTag:1];
if ([indexPath row] == 1 || [indexPath row] == 2)
{
[label setTextColor:[UIColor redColor]];
}
else if ([indexPath row] == 3)
{
[label setTextColor:[UIColor colorWithRed:0.0f green:150.f/255.f blue:30.f/255.f alpha:1.0f]];
}
else if ([indexPath row] == 5)
{
[label setTextColor:[UIColor colorWithRed:155.f/255.f green:145.f/255.f blue:0.0f alpha:1.0f]];
}
[[cell contentView] addSubview:label];
}
NSString *text = [cardInfo objectAtIndex:[indexPath row]];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN *2), 20000000000000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
if (!label)
{
label = (UILabel *)[cell.contentView viewWithTag:1];
}
[label setText:text];
[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN *2), MAX(size.height, 30.0f))];
// Configure the cell...
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *text = [cardInfo objectAtIndex:[indexPath row]];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN *2), 20000000000000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 30.0f);
return height + (CELL_CONTENT_MARGIN * 2);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个错误:
当您构建单元格的视图层次结构时,您永远不应该引用行号。为什么?因为单元格可以重复用于不同的行!这就是 dequeueReusableCellWithIdentifier: 的全部内容。
相反,为标签的标签定义一个常量:
使用该常量设置标签:
稍后当您需要获取标签以设置其文本时,再次使用该常量:
This is an error:
When you are constructing the cell's view hierarchy, you should never refer to the row number. Why? Because a cell can be reused for a different row! That's what
dequeueReusableCellWithIdentifier:
is all about.Instead, define a constant for your label's tag:
Use that constant to set the tag:
and later when you need to fetch the label to set its text, use the constant again:
如果其他人遇到这个问题,我想出了一个解决方法。
经过一番挖掘后,我发现当源字符串长度达到 41,000 左右时,它开始导致此绘图错误。因此,我将超过 30,000 个以上的字符串拆分,并向表中添加了多行。现在它显示整个文本墙。
I figured out a workaround, if anyone else runs into this.
After some digging around, I found out that when the source string length gets to around 41,000, it starts causing this drawing error. So I split up any string over ~30,000 and added multiple rows to the table. It now displays the entire wall of text.