Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
IPInsetLabel: a simple UILabel subclass that adds padding insets and auto-height-resizing
//
// IPInsetLabel.h
// Instapaper
//
// Created by Marco Arment on 7/23/11.
// Copyright 2011 Instapaper LLC, released to the public domain.
//
#import <UIKit/UIKit.h>
@interface IPInsetLabel : UILabel
@property (nonatomic, assign) UIEdgeInsets insets;
- (void)resizeHeightToFitText;
@end
//
// IPInsetLabel.m
// Instapaper
//
// Created by Marco Arment on 7/23/11.
// Copyright 2011 Instapaper LLC, released to the public domain.
//
#import "IPInsetLabel.h"
@implementation IPInsetLabel
@synthesize insets;
- (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;
}
@end

This is a great method, Marco!

Perhaps one suggestion: setting the frame to the instance's bounds prevents explicit instructions for points of origin. This seems to work well if you need to pass in origins in initWithFrame:

self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, frame.size.width, frame.size.height);

mokagio commented Jan 7, 2013

+1

Useful class ! Thanks

trant commented Jun 17, 2013

I have done a small change in order to keep the original origin ( so that the label doesn't move from place when the method is used )

  • (void)resizeHeightToFitText
    {

    //save initial origin position
    CGPoint origin = self.frame.origin;

    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;

    frame.origin = origin;
    self.frame = frame;
    }

Thanks is very useful class :)

Looks like this class needs an update for iOS 7. Xcode is dumping out a warning about the use of a deprecated method:

IPInsetLabel.m:24:33: 'sizeWithFont:constrainedToSize:lineBreakMode:' is deprecated: first deprecated in iOS 7.0 - Use -boundingRectWithSize:options:attributes:context:

Here's the update for the iOS 7 deprecation noted by @bomalley. I've also included the origin fix by @jeebster:

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

    CGRect newSize = [self.text boundingRectWithSize:CGSizeMake(textWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : self.font} context:nil];

    frame.size.height = newSize.size.height + self.insets.top + self.insets.bottom;
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, frame.size.width, frame.size.height);
}

Thanks all for your work! I just pushed a CocoaPod out for this code up to @danomatika's fixes, with additions from @soffes/SAMLabel. It can be found at @doublerebel/IPInsetLabel or on Cocoapods as IPInsetLabel. Hope to see this lib continue, glad to accept any PRs!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment