如何在没有自定义单元格的UITableViewCell中包装文本

时间:2022-12-25 22:18:21

This is on iPhone 0S 2.0. Answers for 2.1 are fine too, though I am unaware of any differences regarding tables.

这是在iphone0s 2.0上。2.1的答案也可以,尽管我不知道关于表的任何差异。

It feels like it should be possible to get text to wrap without creating a custom cell, since a UITableViewCell contains a UILabel by default. I know I can make it work if I create a custom cell, but that's not what I'm trying to achieve - I want to understand why my current approach doesn't work.

感觉应该可以在不创建自定义单元格的情况下将文本打包,因为UITableViewCell默认包含一个UILabel。我知道,如果我创建一个自定义单元格,我可以让它工作,但这不是我想要实现的——我想知道为什么我当前的方法不能工作。

I've figured out that the label is created on demand (since the cell supports text and image access, so it doesn't create the data view until necessary), so if I do something like this:

我发现标签是按需创建的(因为单元格支持文本和图像访问,所以在必要时它不会创建数据视图),所以如果我这样做:

cell.text = @""; // create the label
UILabel* label = (UILabel*)[[cell.contentView subviews] objectAtIndex:0];

then I get a valid label, but setting numberOfLines on that (and lineBreakMode) doesn't work - I still get single line text. There is plenty of height in the UILabel for the text to display - I'm just returning a large value for the height in heightForRowAtIndexPath.

然后我得到一个有效的标签,但是在那个(和换行模式)上设置numberOfLines不起作用——我仍然得到单行文本。UILabel中有大量的高度供文本显示——我只是为heightForRowAtIndexPath中的高度返回一个大值。

9 个解决方案

#1


273  

Here is a simpler way, and it works for me:

这里有一个更简单的方法,它对我很有效:

Inside your cellForRowAtIndexPath: function. The first time you create your cell:

在你cellForRowAtIndexPath:函数。第一次创建单元格时:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];
}

You'll notice that I set the number of lines for the label to 0. This lets it use as many lines as it needs.

您会注意到我将标签的行数设置为0。这使它可以根据需要使用任意多的行。

The next part is to specify how large your UITableViewCell will be, so do that in your heightForRowAtIndexPath function:

下一部分是指定UITableViewCell的大小,请在heightForRowAtIndexPath函数中这样做:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:17.0];
    CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
    CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

    return labelSize.height + 20;
}

I added 20 to my returned cell height because I like a little buffer around my text.

我在返回的单元格高度上增加了20,因为我喜欢文本周围有一个小的缓冲区。

#2


15  

Updated Tim Rupe's answer for iOS7:

更新了Tim Rupe对iOS7的回答:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
    cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:17.0];

    NSAttributedString *attributedText =
        [[NSAttributedString alloc]
            initWithString:cellText
            attributes:@
            {
                NSFontAttributeName: cellFont
            }];
    CGRect rect = [attributedText boundingRectWithSize:CGSizeMake(tableView.bounds.size.width, CGFLOAT_MAX)
                                               options:NSStringDrawingUsesLineFragmentOrigin
                                               context:nil];
    return rect.size.height + 20;
}

#3


3  

A brief comment / answer to record my experience when I had the same problem. Despite using the code examples, the table view cell height was adjusting, but the label inside the cell was still not adjusting correctly - solution was that I was loading my cell from a custom NIB file, which happens after the cell height in adjusted.

当我遇到同样的问题时,用简短的评论/回答来记录我的经验。尽管使用了代码示例,但是表视图单元格高度正在调整,但是单元格内部的标签仍然没有正确地调整——解决方案是我正在从一个自定义NIB文件中加载单元格,这发生在调整单元格高度之后。

And I had my settings inside the NIB file to not wrap text, and only have 1 line for the label; the NIB file settings were overriding the settings I adjusted inside the code.

我在NIB文件中设置了我的设置而不是包装文本,只有一行标签;NIB文件设置覆盖了我在代码中调整的设置。

The lesson I took was to make sure to always bear in mind what the state of the objects are at each point in time - they might not have been created yet! ... hth someone down the line.

我得到的教训是,一定要时刻记住物体在每个时刻的状态——它们可能还没有被创造出来!…把某人赶下队伍。

#4


2  

If we are to add only text in UITableView cell, we need only two delegates to work with (no need to add extra UILabels)

如果我们只在UITableView单元格中添加文本,我们只需要使用两个委托(不需要添加额外的UILabels)

1) cellForRowAtIndexPath

1)cellForRowAtIndexPath

2) heightForRowAtIndexPath

2)heightForRowAtIndexPath

This solution worked for me:-

这个办法对我起作用了:-

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;

    [cell setSelectionStyle:UITableViewCellSelectionStyleGray]; 
    cell.textLabel.text = [mutArr objectAtIndex:indexPath.section];
    NSLog(@"%@",cell.textLabel.text);

    cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrow.png" ]];

    return cell;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{  
    CGSize labelSize = CGSizeMake(200.0, 20.0);

    NSString *strTemp = [mutArr objectAtIndex:indexPath.section];

    if ([strTemp length] > 0)
        labelSize = [strTemp sizeWithFont: [UIFont boldSystemFontOfSize: 14.0] constrainedToSize: CGSizeMake(labelSize.width, 1000) lineBreakMode: UILineBreakModeWordWrap];

    return (labelSize.height + 10);
}

Here the string mutArr is a mutable array from which i am getting my data.

这里的字符串mutArr是一个可变数组,从中获取数据。

EDIT :- Here is the array which I took.

编辑:-这是我取的数组。

mutArr= [[NSMutableArray alloc] init];

[mutArr addObject:@"HEMAN"];
[mutArr addObject:@"SUPERMAN"];
[mutArr addObject:@"Is SUPERMAN powerful than HEMAN"];
[mutArr addObject:@"Well, if HEMAN is weaker than SUPERMAN, both are friends and we will never get to know who is more powerful than whom because they will never have a fight among them"];
[mutArr addObject:@"Where are BATMAN and SPIDERMAN"];

#5


1  

Now the tableviews can have self-sizing cells. Set the table view up as follows

现在,tableview可以有自调整大小的单元格。将表视图设置为如下所示

tableView.estimatedRowHeight = 85.0 //use an appropriate estimate tableView.rowHeight = UITableViewAutomaticDimension

tableView. estimatedrowheight = 85.0 // /使用合适的估计值tableView。rowHeight = UITableViewAutomaticDimension

Apple Reference

苹果公司参考

#6


0  

I use the following solutions.

我使用以下的解决方案。

The data is provided separately in a member:

资料在一名成员内分别提供:

-(NSString *)getHeaderData:(int)theSection {
    ...
    return rowText;
}

The handling can be easily done in cellForRowAtIndexPath. Define the cell / define the font and assign these values to the result "cell". Note that the numberoflines is set to "0", which means take what is needed.

处理可以在cellForRowAtIndexPath中轻松完成。定义单元格/定义字体,并将这些值赋给结果“单元格”。注意,numberoflines被设置为“0”,这意味着取所需要的。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    UIFont *cellFont = [UIFont fontWithName:@"Verdana" size:12.0];
    cell.textLabel.text= [self getRowData:indexPath.section];
    cell.textLabel.font = cellFont;
    cell.textLabel.numberOfLines=0;
    return cell;
}

In heightForRowAtIndexPath, I calculate the heights of the wrapped text. The boding size shall be related to the width of your cell. For iPad this shall be 1024. For iPhone en iPod 320.

在heightForRowAtIndexPath中,我计算包装文本的高度。发条尺寸应与单元的宽度有关。iPad应该是1024。iPhone en iPod 320。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIFont *cellFont = [UIFont fontWithName:@"Verdana" size:12.0];
    CGSize boundingSize = CGSizeMake(1024, CGFLOAT_MAX);
    CGSize requiredSize = [[self getRowData:indexPath.section] sizeWithFont:cellFont constrainedToSize:boundingSize lineBreakMode:UILineBreakModeWordWrap];
    return requiredSize.height;    
}

#7


0  

I found this to be quite simple and straightForward :

我发现这非常简单和直接:

[self.tableView setRowHeight:whatEvereight.0f];

for e.g. :

例如:

[self.tableView setRowHeight:80.0f];

This may or may not be the best / standard approach to do so, but it worked in my case.

这可能不是最好的/标准的方法,但它在我的案例中发挥了作用。

#8


-1  

I think this is a better and shorter solution. Just format the UILabel (textLabel) of the cell to auto calculate for the height by specifying sizeToFit and everything should be fine.

我认为这是一个更好更短的解决方案。只需格式化单元格的UILabel (textLabel),通过指定sizeToFit来计算高度,一切都应该没问题。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    cell.textLabel.text = @"Whatever text you want to put here is ok";
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    [cell.textLabel sizeToFit];

    return cell;
}

#9


-2  

I don't think you can manipulate a base UITableViewCell's private UILabel to do this. You could add a new UILabel to the cell yourself and use numberOfLines with sizeToFit to size it appropriately. Something like:

我认为你不能操纵一个基础UITableViewCell的私有UILabel来做这个。你可以自己在细胞中添加一个新的UILabel,并使用sizeToFit的numberOfLines来适当地调整大小。喜欢的东西:

UILabel* label = [[UILabel alloc] initWithFrame:cell.frame];
label.numberOfLines = <...an appriate number of lines...>
label.text = <...your text...>
[label sizeToFit];
[cell addSubview:label];
[label release];

#1


273  

Here is a simpler way, and it works for me:

这里有一个更简单的方法,它对我很有效:

Inside your cellForRowAtIndexPath: function. The first time you create your cell:

在你cellForRowAtIndexPath:函数。第一次创建单元格时:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];
}

You'll notice that I set the number of lines for the label to 0. This lets it use as many lines as it needs.

您会注意到我将标签的行数设置为0。这使它可以根据需要使用任意多的行。

The next part is to specify how large your UITableViewCell will be, so do that in your heightForRowAtIndexPath function:

下一部分是指定UITableViewCell的大小,请在heightForRowAtIndexPath函数中这样做:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:17.0];
    CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
    CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

    return labelSize.height + 20;
}

I added 20 to my returned cell height because I like a little buffer around my text.

我在返回的单元格高度上增加了20,因为我喜欢文本周围有一个小的缓冲区。

#2


15  

Updated Tim Rupe's answer for iOS7:

更新了Tim Rupe对iOS7的回答:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
    cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:17.0];

    NSAttributedString *attributedText =
        [[NSAttributedString alloc]
            initWithString:cellText
            attributes:@
            {
                NSFontAttributeName: cellFont
            }];
    CGRect rect = [attributedText boundingRectWithSize:CGSizeMake(tableView.bounds.size.width, CGFLOAT_MAX)
                                               options:NSStringDrawingUsesLineFragmentOrigin
                                               context:nil];
    return rect.size.height + 20;
}

#3


3  

A brief comment / answer to record my experience when I had the same problem. Despite using the code examples, the table view cell height was adjusting, but the label inside the cell was still not adjusting correctly - solution was that I was loading my cell from a custom NIB file, which happens after the cell height in adjusted.

当我遇到同样的问题时,用简短的评论/回答来记录我的经验。尽管使用了代码示例,但是表视图单元格高度正在调整,但是单元格内部的标签仍然没有正确地调整——解决方案是我正在从一个自定义NIB文件中加载单元格,这发生在调整单元格高度之后。

And I had my settings inside the NIB file to not wrap text, and only have 1 line for the label; the NIB file settings were overriding the settings I adjusted inside the code.

我在NIB文件中设置了我的设置而不是包装文本,只有一行标签;NIB文件设置覆盖了我在代码中调整的设置。

The lesson I took was to make sure to always bear in mind what the state of the objects are at each point in time - they might not have been created yet! ... hth someone down the line.

我得到的教训是,一定要时刻记住物体在每个时刻的状态——它们可能还没有被创造出来!…把某人赶下队伍。

#4


2  

If we are to add only text in UITableView cell, we need only two delegates to work with (no need to add extra UILabels)

如果我们只在UITableView单元格中添加文本,我们只需要使用两个委托(不需要添加额外的UILabels)

1) cellForRowAtIndexPath

1)cellForRowAtIndexPath

2) heightForRowAtIndexPath

2)heightForRowAtIndexPath

This solution worked for me:-

这个办法对我起作用了:-

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;

    [cell setSelectionStyle:UITableViewCellSelectionStyleGray]; 
    cell.textLabel.text = [mutArr objectAtIndex:indexPath.section];
    NSLog(@"%@",cell.textLabel.text);

    cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrow.png" ]];

    return cell;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{  
    CGSize labelSize = CGSizeMake(200.0, 20.0);

    NSString *strTemp = [mutArr objectAtIndex:indexPath.section];

    if ([strTemp length] > 0)
        labelSize = [strTemp sizeWithFont: [UIFont boldSystemFontOfSize: 14.0] constrainedToSize: CGSizeMake(labelSize.width, 1000) lineBreakMode: UILineBreakModeWordWrap];

    return (labelSize.height + 10);
}

Here the string mutArr is a mutable array from which i am getting my data.

这里的字符串mutArr是一个可变数组,从中获取数据。

EDIT :- Here is the array which I took.

编辑:-这是我取的数组。

mutArr= [[NSMutableArray alloc] init];

[mutArr addObject:@"HEMAN"];
[mutArr addObject:@"SUPERMAN"];
[mutArr addObject:@"Is SUPERMAN powerful than HEMAN"];
[mutArr addObject:@"Well, if HEMAN is weaker than SUPERMAN, both are friends and we will never get to know who is more powerful than whom because they will never have a fight among them"];
[mutArr addObject:@"Where are BATMAN and SPIDERMAN"];

#5


1  

Now the tableviews can have self-sizing cells. Set the table view up as follows

现在,tableview可以有自调整大小的单元格。将表视图设置为如下所示

tableView.estimatedRowHeight = 85.0 //use an appropriate estimate tableView.rowHeight = UITableViewAutomaticDimension

tableView. estimatedrowheight = 85.0 // /使用合适的估计值tableView。rowHeight = UITableViewAutomaticDimension

Apple Reference

苹果公司参考

#6


0  

I use the following solutions.

我使用以下的解决方案。

The data is provided separately in a member:

资料在一名成员内分别提供:

-(NSString *)getHeaderData:(int)theSection {
    ...
    return rowText;
}

The handling can be easily done in cellForRowAtIndexPath. Define the cell / define the font and assign these values to the result "cell". Note that the numberoflines is set to "0", which means take what is needed.

处理可以在cellForRowAtIndexPath中轻松完成。定义单元格/定义字体,并将这些值赋给结果“单元格”。注意,numberoflines被设置为“0”,这意味着取所需要的。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    UIFont *cellFont = [UIFont fontWithName:@"Verdana" size:12.0];
    cell.textLabel.text= [self getRowData:indexPath.section];
    cell.textLabel.font = cellFont;
    cell.textLabel.numberOfLines=0;
    return cell;
}

In heightForRowAtIndexPath, I calculate the heights of the wrapped text. The boding size shall be related to the width of your cell. For iPad this shall be 1024. For iPhone en iPod 320.

在heightForRowAtIndexPath中,我计算包装文本的高度。发条尺寸应与单元的宽度有关。iPad应该是1024。iPhone en iPod 320。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIFont *cellFont = [UIFont fontWithName:@"Verdana" size:12.0];
    CGSize boundingSize = CGSizeMake(1024, CGFLOAT_MAX);
    CGSize requiredSize = [[self getRowData:indexPath.section] sizeWithFont:cellFont constrainedToSize:boundingSize lineBreakMode:UILineBreakModeWordWrap];
    return requiredSize.height;    
}

#7


0  

I found this to be quite simple and straightForward :

我发现这非常简单和直接:

[self.tableView setRowHeight:whatEvereight.0f];

for e.g. :

例如:

[self.tableView setRowHeight:80.0f];

This may or may not be the best / standard approach to do so, but it worked in my case.

这可能不是最好的/标准的方法,但它在我的案例中发挥了作用。

#8


-1  

I think this is a better and shorter solution. Just format the UILabel (textLabel) of the cell to auto calculate for the height by specifying sizeToFit and everything should be fine.

我认为这是一个更好更短的解决方案。只需格式化单元格的UILabel (textLabel),通过指定sizeToFit来计算高度,一切都应该没问题。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    cell.textLabel.text = @"Whatever text you want to put here is ok";
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    [cell.textLabel sizeToFit];

    return cell;
}

#9


-2  

I don't think you can manipulate a base UITableViewCell's private UILabel to do this. You could add a new UILabel to the cell yourself and use numberOfLines with sizeToFit to size it appropriately. Something like:

我认为你不能操纵一个基础UITableViewCell的私有UILabel来做这个。你可以自己在细胞中添加一个新的UILabel,并使用sizeToFit的numberOfLines来适当地调整大小。喜欢的东西:

UILabel* label = [[UILabel alloc] initWithFrame:cell.frame];
label.numberOfLines = <...an appriate number of lines...>
label.text = <...your text...>
[label sizeToFit];
[cell addSubview:label];
[label release];