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

时间:2015-01-01 17:34:01

标签: ios objective-c uilabel

我想创建一个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;

}

当我运行这些行没有任何反应时,标签不会改变,我无法理解,因为它应该。

13 个答案:

答案 0 :(得分: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。

答案 1 :(得分:3)

有一个非常好的教程可以根据其内容计算uitableView的动态高度。在这里,他们扩展/定制UILabel以适应动态内容。

http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout

答案 2 :(得分:2)

框架设置无效,因为自动布局已开启,尝试在设置框架时将标签的translatesAutoresizingMaskIntoConstraints属性设置为YES,或者您可以关闭自动布局。和 [cell.lbl setFrame:CGRectMake(0,0,x,cell.lbl.frame.origin.y)];应该是

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

答案 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;
}

答案 4 :(得分:2)

尝试以下方法获取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;
}

问候。

答案 5 :(得分: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;

答案 6 :(得分:2)

在“layoutSubviews”方法中使用自定义UITableViewCell类和setframe

` - (void)layoutSubviews {

[super layoutSubviews]; 

[self.lbl setFrame:...];

}`

答案 7 :(得分:2)

最好的方法是为UILabel应用适当的自动布局约束。然后,如果您的目标是iOS 8,则将setview的行高属性设置为UITableViewAutomaticDimension。 或

将高度限制设置为tableviewviewDidAppear

 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];
            }

如果您的自动布局限制很好,那应该可以胜任。

答案 8 :(得分:1)

在标签上创建固定宽度和固定高度约束(通过界面构建​​器),将它们暴露给视图控制器(再次通过界面构建​​器),并直接操作layoutconstraints:

// 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];

答案 9 :(得分: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

然后试试:

- (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];
}

答案 10 :(得分:1)

我设法使用CustomTableViewCell做了类似的事情,通过将自定义单元格的UILabel属性的translatesAutoresizingMaskIntoConstraints设置为true,然后通过调用customCell.frame = CGRectMake将标签的框架设置为您想要的任何内容(什么,永远,你,想要)。唯一的问题是,你会得到一个警告说&#34;无法同时满足约束。&#34;,直到你将translatesAutoresizingMaskIntoConstraints更改为false。当您通过可视格式手动设置约束时会发生这种情况。不知道如何通过AutoLayout来做到这一点。我是初学者,但无论如何都想与你分享我的发现,希望它有所帮助。干杯!

答案 11 :(得分:0)

检查这个是否有帮助..

UILabel *type;
type.frame=[self calculateHeightOfTextFromWidth:type withText:type.text];

-(CGRect) calculateHeightOfTextFromWidth:(UILabel*)detailLabel withText:(NSString*)text {        

    CGRect currentFrame = detailLabel.frame;
    CGSize max = CGSizeMake(detailLabel.frame.size.width, 500);

    CGSize expected = [text sizeWithFont:detailLabel.font constrainedToSize:max lineBreakMode:detailLabel.lineBreakMode]; 
    currentFrame.size.height = expected.height;
    return currentFrame;
}

答案 12 :(得分:0)

这是一种方法,应根据高度和文本字符串返回UILabel宽度的正确宽度。使用此方法返回的宽度设置单元格框架。

CGFloat *maxWidth = the maximum width you would want your label to be
CGFloat *labelHeight = the height of your label
CGFloat *additionalWidthBuffer = any fixed extra width on your label  


-(CGFloat)labelHeightForText:(NSString*) text
{
   UIFont * font = [UIFont systemFontOfSize:15.0f];
   CGFloat width = [text boundingRectWithSize:CGSizeMake(maxWidth, labelHeight)    options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName: font} context:nil].size.width;

  return height + additionalWidthBuffer;
}