Mick Byrne
Mick Byrne

Reputation: 14484

Multiline UILabel with padding in autolayout, in UITableView

I have a UILabel in a UITableView that should be a maximum of 2 lines and have a bit of padding around it (7 left and right and 2 top and bottom). I'm using autolayout and targeting only iOS6 and above. All views are being created and added programatically.

I've subclassed my UILabel, here's the init method:

- (id)init
{
self = [super init];

self.translatesAutoresizingMaskIntoConstraints = NO;
self.numberOfLines = 2;
self.backgroundColor = UIColorFromARGB(0x99000000);
self.textColor = [UIColor whiteColor];
self.font = [UIFont boldSystemFontOfSize:14.0f];

return self;
}

If I add this in, I get the right padding, but it makes it just one line:

- (void)drawTextInRect:(CGRect)rect {
UIEdgeInsets insets = {2, 7, 2, 7};
return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}

I've seen this answer a few times, but it doesn't work for me (no effect):

- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines
{
UIEdgeInsets insets = {2, 7, 2, 7};
    return [super textRectForBounds:UIEdgeInsetsInsetRect(bounds,insets) limitedToNumberOfLines:numberOfLines];
}

Does it make a difference that its in a table view? Any help would be appreciated.

Upvotes: 3

Views: 4556

Answers (2)

Rudolf J
Rudolf J

Reputation: 517

@implementation InsetLabel

- (void) setInsets:(UIEdgeInsets)insets
    {
    _insets = insets ;
    [self invalidateIntrinsicContentSize] ;
    }

- (void)drawTextInRect:(CGRect)rect
    {
    return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.insets)];
    }

- (void)resizeHeightToFitText
    {
    CGRect frame = [self frame];
    CGFloat textWidth = frame.size.width - (self.insets.left + self.insets.right);

    CGSize newSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(textWidth, 1000000) lineBreakMode:self.lineBreakMode];
    frame.size.height = newSize.height + self.insets.top + self.insets.bottom;
    self.frame = frame;
    }

- (CGSize) intrinsicContentSize
    {
    CGSize superSize = [super intrinsicContentSize] ;
    superSize.height += self.insets.top + self.insets.bottom ;
    superSize.width += self.insets.left + self.insets.right ;
    return superSize ;
    }
- (void)layoutSubviews
{
    [super layoutSubviews];
    [self resizeHeightToFitText];
}

This works even better imho.

Upvotes: 2

leftspin
leftspin

Reputation: 2488

As you saw in my above comment, you didn't really say what it's doing that you don't expect. I've just done this myself, and this works with autolayout:

@implementation InsetLabel

- (void) setInsets:(UIEdgeInsets)insets
    {
    _insets = insets ;
    [self invalidateIntrinsicContentSize] ;
    }

- (void)drawTextInRect:(CGRect)rect
    {
    return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.insets)];
    }

- (void)resizeHeightToFitText
    {
    CGRect frame = [self bounds];
    CGFloat textWidth = frame.size.width - (self.insets.left + self.insets.right);

    CGSize newSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(textWidth, 1000000) lineBreakMode:self.lineBreakMode];
    frame.size.height = newSize.height + self.insets.top + self.insets.bottom;
    self.frame = frame;
    }

- (CGSize) intrinsicContentSize
    {
    CGSize superSize = [super intrinsicContentSize] ;
    superSize.height += self.insets.top + self.insets.bottom ;
    superSize.width += self.insets.left + self.insets.right ;
    return superSize ;
    }

@end

Upvotes: 10

Related Questions