基于文本长度编程自定义UILabel宽度

4

我想创建一个比同一UILabel中文本宽度略宽的UILabel。我查看了很多问题并尝试了它们的答案,但仍然找不到正确的方法。我可以获取文本的宽度,但无法重新绘制框架。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {

static NSString *Cell = @"cell";
LikeActivityTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Cell];

cell.lbl.backgroundColor = [UIColor colorWithRed:7.0 green:4.0 blue:55.0 alpha:0.7];

NSString *lblString = [NSString stringWithFormat:@"%@", object[@"content"]];
cell.lbl.text = lblString;

float widthIs =  [cell.lbl.text
         boundingRectWithSize:cell.lbl.frame.size
         options:NSStringDrawingUsesLineFragmentOrigin
         attributes:@{ NSFontAttributeName:cell.lbl.font }
         context:nil]
        .size.width;


    float heightIs =
        [cell.lbl.text
         boundingRectWithSize:cell.lbl.frame.size
         options:NSStringDrawingUsesLineFragmentOrigin
         attributes:@{ NSFontAttributeName:cell.lbl.font }
         context:nil]
        .size.height;
NSLog(@"CELL TEXT WIDTH %f", widthIs);

int x = widthIs + 10;
int y = heightIs;
// ATTEMPT 1   
[cell.lbl setFrame:CGRectMake(0,0,x,cell.lbl.frame.origin.y)];

// ATTEMPT 2
cell.lbl.frame = CGRectMake(0, 0, x, cell.lbl.frame.origin.y);

return cell;

}

当我运行这些代码时,没有任何效果,标签没有发生改变,这让我困惑,因为它本应该有所改变。

1
如果你想改变宽度,那么为什么要不停地改变高度呢?而且,宽度和高度与x和y相同吗?真的吗?_真的吗_? - matt
@matt 我已经更新了问题,我忘记了y值。我正在编辑y值是为了测试目的,而且我对这个大小调整的东西不是很熟悉。我正在使用一个自动布局项目,但是这个标签没有使用约束。我有一个自定义的表格视图单元格类,我在那里创建了这个标签。 - rihekopo
@HashmatKhalil 我之前可以通过这种方式改变一个 UIView 的大小,我认为这个方法也应该有效。 - rihekopo
请阅读文档。您误解了自动布局:https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/Introduction/Introduction.html - Hashmat Khalil
@matt,我已经更新了我的代码。我有一个非常基本的表视图,我只想正确地显示那个标签。 - rihekopo
显示剩余4条评论
13个回答

3

只需使用自动布局,即可使标签的宽度环绕文本。如果文本只有一行,并且您希望标签尺寸围绕其适合,您只需要添加一个约束来设置前导属性或中心X(以及顶部/居中Y和高度的约束),并确保您添加

[yourLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[yourLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];

将其添加到子视图后,如果文本是多行的或可能是多行的,则需要编写更多代码。您需要设置垂直轴的压缩阻力和拉伸。

[yourLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
    [yourLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];

另外添加:
- (void)layoutSubviews {
    if (!CGRectIsEmpty(self.frame)) {
        _featureDescriptionLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.contentView.frame)-59-5;
    }
    [super layoutSubviews];
}

这段代码需要放在你自定义的表格视图单元格中。将最大布局宽度设置为文本可以在单元格内的最宽宽度。

如果是多行文本,请不要忘记将行数设置为0。


3

2
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    CGSize itemTextSize = [@"label text which you want to set" boundingRectWithSize:CGSizeMake(100, 30) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont fontWithName:@"Helvetica Neue" size:12.5]} context:nil].size;
    return itemTextSize.height + 10;


}


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

    static NSString *CellIdentifier = @"cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

    }

    CGSize itemTextSize = [@"label text which you want to set" boundingRectWithSize:CGSizeMake(100, 30) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont fontWithName:@"Helvetica Neue" size:12.5]} context:nil].size;
    itemTextSize.width = itemTextSize.width + 10;
    [cell.lbl setFrame:CGRectMake(0, 0, itemTextSize.width, itemTextSize.height)];

    return cell;
}

2

尝试以下方法用于tableView中的cellForRow以及获取文本大小。希望这对您有所帮助。

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   static NSString* cellIdentifier = @"CellIdentifier";
  UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    cell.selectionStyle=UITableViewCellSelectionStyleNone;
 UILabel *lblComment;
 if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        lblComment=[[UILabel alloc] init];
        lblComment.backgroundColor=[UIColor clearColor];
        lblComment.font=[UIFont fontWithName:FONT_NAME size:FONT_SIZE];
        lblComment.numberOfLines=0;
        lblComment.lineBreakMode=NSLineBreakByWordWrapping;
        [cell.contentView addSubview:lblComment];
}else{
        lblComment=(UILabel *)[[cell.contentView subviews] objectAtIndex:0];
 }
  lblComment.tag=[self realRowNumberForIndexPath:indexPath inTableView:tableView] + 0;
  CGSize Comment_Size = [self GetLAbelSize:lblComment.text LabelFont:FONT_NAME width:FONT_SIZE];
  lblComment.frame = CGRectMake(lblComment.frame.origin.x, lblComment.frame.origin.y, Comment_Size.width, Comment_Size.height);
  return cell;
 }

-(CGSize)GetLAbelSize:(NSString *)str_Text LabelFont:(UIFont *)font width:(float)width
{
    CGSize constraintSize = CGSizeMake(width,MAXFLOAT);
   // CGSize labelSize = [str_Text sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
    CGRect boundingRect = [str_Text boundingRectWithSize:constraintSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil];
    CGSize labelSize = boundingRect.size;
    return labelSize;
}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGSize lblComment = [self GetLAbelHeight:[array_Comment objectAtIndex:indexPath.row]  LabelFont:FONT_NAME width:FONT_SIZE];
    float totalHeight = lblComment.height+5;
    return totalHeight;
}


- (NSInteger)realRowNumberForIndexPath:(NSIndexPath *)indexPath inTableView:(UITableView *)tableView
{
NSInteger retInt = 0;
if (!indexPath.section)
{
    return indexPath.row;
}
for (int i=0; i<indexPath.section;i++)
{
    retInt += [tableView numberOfRowsInSection:i];
}
return retInt + indexPath.row;
}

Regards.


我能获取宽度和高度。问题是我不能编辑框架。 - rihekopo
您正在使用UITableViewCell的标签。请创建所需属性的自定义标签,然后将其添加到cell.contentView中。然后从内容视图中获取标签,然后调整大小。请查看我上面提到的cellForRowAtINdexPath方法。我请求您尝试在TableView中使用与我上面提到的标签相同的方法。 - Nikh1414

2

制作自定义的UITableViewCell。我们将其称为CustomCell。为CustomCell创建一个XIB、.h和.m文件。在XIB中,拖动一个表格视图单元格,使其是视图中唯一的东西。将标签和其他您希望添加到单元格中的视图添加到其中。以任何有意义的方式向视图添加约束条件,并确保这些约束条件中的一个是标签的宽度约束条件。将此约束条件和标签连接到CustomCell.h。您的CustomCell.h将如下所示:

@interface CustomCell : UITableViewCell

@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *labelWidth;

@end

现在您可以将CustomCell从XIB复制/粘贴到要使用该单元格的表中。然后在cellForRowAtIndexPath:中,您可以按以下方式调整标签的宽度,CustomCell中的其他视图也会相应地调整(感谢自动布局!)。

CGSize size = [self.label sizeThatFits:CGSizeMake(self.frame.size.width, self.frame.size.height)];
self.labelWidth.constant = size.width;

2

请在自定义的UITableViewCell类中,在其“layoutSubviews”方法中设置frame。

`-(void)layoutSubviews {

[super layoutSubviews]; 

[self.lbl setFrame:...];

}`


2

最好的方法是为UILabel应用正确的自动布局约束。如果您的目标是iOS 8,则将表视图的行高属性设置为UITableViewAutomaticDimension

或者为tableview设置一个高度约束,并在viewDidAppear中完成。

 self.tableViewHeightConstraint.constant = self.tableView.contentSize.height;

viewWillLayoutSubviews 方法中获取 tableViewCell 对象。
CGFloat width = label.bounds.size.width;
            if ( label.preferredMaxLayoutWidth != width )
            {
                label.preferredMaxLayoutWidth = width;

                [tableViewCell setNeedsLayout];
                [tableViewCell layoutIfNeeded];
            }

如果您的自动布局约束正确,那么这应该可以完成工作。

2

由于启用了自动布局,因此框架设置无效,请在设置标签的帧时将属性设置为YES,或者可以关闭自动布局。并且 [cell.lbl setFrame:CGRectMake(0,0,x,cell.lbl.frame.origin.y)]; 应该改为

[cell.lbl setFrame:CGRectMake(0,0,x, heightIs)];


1
通过界面构建器在标签上创建固定宽度和固定高度的约束条件,将其暴露给视图控制器(同样通过界面构建器),并直接操作布局约束条件:
// in the .h created by interface builder
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *labelWidth;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *labelHeight;

...

// in the implementation
[self.labelWidth setConstant:widthIs + 10];
[self.labelHeight setConstant:heightIs];

由于表视图,出现了这个错误:“从DevTableViewController到NSLayoutConstraint的labelWidth输出无效。输出不能连接到重复的内容。” - rihekopo
你将它们作为单独的约束添加到同一个元素中了吗?现在,先尝试宽度,如果可以,请随后添加高度约束。要添加约束,请突出显示标签,然后选择“编辑器|固定|宽度”。然后,使用助理编辑器并从约束(图形或从文档大纲内)ctrl-click-and-drag到.h文件,并添加插座。 - Danny Daglas
1
@bushiko 你需要将约束连接到你的UITableViewCell子类中,而不是在你的视图控制器中! - David Ganster

1

假设你创建了自定义单元格:

@implementation LikeActivityTableViewCell
-(id)init{
     self = [super init];
    if(self){
        self.lbl = [[UILabel alloc] init];
        self.lbl.font = [UIFont fontWithName:@"Arial" size:16]; // Set the font you want
        self.lbl.backgroundColor = [UIColor colorWithRed:7.0/255 green:4.0/255 blue:55.0/255 alpha:0.7]; // Dont forget "/255"
        [self.contentView addSubview:self.lbl];
    }
    return self;
}
@end

Then just try:

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

    static NSString *Cell = @"cell";
    LikeActivityTableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:Cell];
    if(!cell){
        cell = [[LikeActivityTableViewCell alloc] init];
    }
    cell.lbl.text = [NSString stringWithFormat:@"Am I cell number %d? No!", indexPath.row * 8]; // Put your text here
    CGSize labelSize = [self getFrameForLabel:cell.lbl];
    labelSize.width += 10.f;
    cell.lbl.frame = CGRectMake(cell.contentView.frame.size.width * 0.5f - labelSize.width * 0.5f,
                                cell.contentView.frame.size.height * 0.5f - labelSize.height * 0.5f,
                                labelSize.width,
                                labelSize.height); // I decided to center the label but you can put 0, 0 as origin
    return cell;
}

-(CGSize)getFrameForLabel:(UILabel*)label{
    NSDictionary *attributes = @{NSFontAttributeName: label.font};
    return [label.text sizeWithAttributes:attributes];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接