Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*.pyc
*~.nib/
build/*
# xcode 4
xcuserdata

# Textmate - if you build your xcode projects with it
*.tm_build_errors
Expand Down
3 changes: 3 additions & 0 deletions MTLabel.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@
/* Begin PBXProject section */
147737C01391B7C100BCB59A /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0420;
};
buildConfigurationList = 147737C31391B7C100BCB59A /* Build configuration list for PBXProject "MTLabel" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
Expand Down
97 changes: 59 additions & 38 deletions MTLabel/MTLabel.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@

#define DEFAULT_FONT_SIZE 12

@interface MTLabel ()
@interface MTLabel ()

-(void)drawTransparentBackground;

@end

CGRect CTLineGetTypographicBoundsAsRect(CTLineRef line, CGPoint lineOrigin) {
CGRect CTLineGetTypographicBoundsAsARect(CTLineRef line, CGPoint lineOrigin) {
CGFloat ascent = 0;
CGFloat descent = 0;
CGFloat leading = 0;
Expand All @@ -51,7 +51,6 @@ @implementation MTLabel
@synthesize _textAlignment;
@synthesize delegate;
@synthesize _adjustSizeToFit;

#pragma mark - Setters

-(void)setNumberOfLines:(int)numberOfLines {
Expand Down Expand Up @@ -85,6 +84,7 @@ -(void)setText:(NSString *)text {
_text = nil;
}

//_text = [[text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] retain];
_text = [text retain];
[self setNeedsDisplay];

Expand Down Expand Up @@ -156,6 +156,7 @@ -(void)setResizeToFitText:(BOOL)resizeToFitText {
if (_shouldResizeToFit != resizeToFitText) {

_shouldResizeToFit = resizeToFitText;
self.clipsToBounds = NO;
[self setNeedsDisplay];
}

Expand Down Expand Up @@ -226,6 +227,7 @@ - (void)setup {
self._font = [UIFont systemFontOfSize:DEFAULT_FONT_SIZE];
self._lineHeight = _font.lineHeight;
self._textAlignment = MTLabelTextAlignmentLeft;
self.contentMode = UIViewContentModeRedraw;
[self setOpaque:NO];
}
-(id)init {
Expand Down Expand Up @@ -333,15 +335,17 @@ - (CGFloat)textOffsetForLine:(CTLineRef)line inRect:(CGRect)rect {

return x;
}
- (void)drawTextInRect:(CGRect)rect inContext:(CGContextRef)context {
- (void)drawTextInRect:(CGRect)rect withFont:(UIFont *)aFont lineHeight:(CGFloat)lineHeight inContext:(CGContextRef)context {

if (!_text) {
return;
}

CGContextClearRect(context, rect);

//Create a CoreText font object with name and size from the UIKit one
CTFontRef font = CTFontCreateWithName((CFStringRef)_font.fontName ,
_font.pointSize,
CTFontRef font = CTFontCreateWithName((CFStringRef)aFont.fontName ,
aFont.pointSize,
NULL);

//Setup the attributes dictionary with font and color
Expand All @@ -360,7 +364,7 @@ - (void)drawTextInRect:(CGRect)rect inContext:(CGContextRef)context {
CTTypesetterRef typeSetter = CTTypesetterCreateWithAttributedString((CFAttributedStringRef)attributedString);

//Start drawing from the upper side of view (the context is flipped, so we need to grab the height to do so)
CGFloat y = self.bounds.origin.y + self.bounds.size.height - _font.ascender;
CGFloat y = rect.origin.y + rect.size.height - aFont.ascender;

BOOL shouldDrawAlong = YES;
int count = 0;
Expand All @@ -374,7 +378,7 @@ - (void)drawTextInRect:(CGRect)rect inContext:(CGContextRef)context {
//Get CoreText to suggest a proper place to place the line break
CFIndex lineLength = CTTypesetterSuggestLineBreak(typeSetter,
currentIndex,
self.bounds.size.width);
rect.size.width);

//Create a new line with from current index to line-break index
CFRange lineRange = CFRangeMake(currentIndex, lineLength);
Expand All @@ -383,18 +387,18 @@ - (void)drawTextInRect:(CGRect)rect inContext:(CGContextRef)context {
//Create a new CTLine if we want to justify the text
if (_textAlignment == MTLabelTextAlignmentJustify) {

CTLineRef justifiedLine = CTLineCreateJustifiedLine(line, 1.0, self.bounds.size.width);
CTLineRef justifiedLine = CTLineCreateJustifiedLine(line, 1.0, rect.size.width);
CFRelease(line); line = nil;

line = justifiedLine;
}

CGFloat x = [self textOffsetForLine:line inRect:self.bounds];
CGFloat x = [self textOffsetForLine:line inRect:rect];

// Draw highlight if color has been set
if (_fontHighlightColor != nil) {
CGContextSetFillColorWithColor(context, _fontHighlightColor.CGColor);
CGRect lineRect = CTLineGetTypographicBoundsAsRect(line, CGPointMake(x, y));// + (self._lineHeight - self._font.pointSize) / 2));
CGRect lineRect = CTLineGetTypographicBoundsAsARect(line, CGPointMake(x, y));// + (self._lineHeight - self._font.pointSize) / 2));

lineRect = CGRectIntegral(lineRect);
lineRect = CGRectInset(lineRect, -1, -1);
Expand Down Expand Up @@ -423,37 +427,41 @@ - (void)drawTextInRect:(CGRect)rect inContext:(CGContextRef)context {
CFRelease(line);

CGFloat minFontSizeChange = 1;
y -= _lineHeight;
y -= lineHeight;

currentIndex += lineLength;
_textHeight += _lineHeight;

if (_adjustSizeToFit && _font.pointSize > _minimumFontSize) {
_textHeight += lineHeight;
if (_adjustSizeToFit && aFont.pointSize > _minimumFontSize) {

if (self.bounds.size.height < _textHeight) {
if (rect.size.height < _textHeight) {

NSString *fontName = _font.fontName;
CGFloat pointSize = _font.pointSize;
CGFloat lineHeightRatio = self._lineHeight / pointSize;
NSString *fontName = aFont.fontName;
CGFloat pointSize = aFont.pointSize;
CGFloat lineHeightRatio = lineHeight / pointSize;
CGFloat newPointSize = pointSize - minFontSizeChange;

// Make sure newPointSize is not less than the _minimumFontSize
newPointSize = newPointSize < _minimumFontSize ? _minimumFontSize : newPointSize;

self._font = [UIFont fontWithName:fontName size:newPointSize];
self._lineHeight = roundf(newPointSize * lineHeightRatio);
UIFont *newFont = [UIFont fontWithName:fontName size:newPointSize];
CGFloat newLineHeight = roundf(newPointSize * lineHeightRatio);

CGContextClearRect(context, self.bounds);
self._font = newFont;
self._lineHeight = newLineHeight;

CGContextClearRect(context, rect);
CFRelease(typeSetter);

return [self drawTextInRect:self.bounds inContext:context];
return [self drawTextInRect:rect withFont:newFont lineHeight:newLineHeight inContext:context];
}
}
}
}

CFRelease(typeSetter);

}

- (void)drawRect:(CGRect)rect {

CGContextRef context = UIGraphicsGetCurrentContext();
Expand All @@ -464,25 +472,39 @@ - (void)drawRect:(CGRect)rect {
CGContextScaleCTM(context, 1.0, -1.0);

CGContextSaveGState(context);

[self drawTextInRect:rect inContext:context];


if (_shouldResizeToFit && self.frame.size.height < _textHeight) {

[self setFrame:CGRectMake(self.frame.origin.x,
self.frame.origin.y,
self.frame.size.width,
_textHeight)];
[self drawTextInRect:rect withFont:self._font lineHeight:self._lineHeight inContext:context];

if (_shouldResizeToFit && rect.size.height < _textHeight) {


CGRect newFrame = CGRectMake(self.frame.origin.x,
self.frame.origin.y,
self.frame.size.width,
_textHeight);
[self setFrame:newFrame];

// Notify delegate that we did change frame
[delegate labelDidChangeFrame:self.frame];

// Ugly hack to avoid content being stretched
[self performSelector:@selector(setNeedsDisplay) withObject:nil afterDelay:0.0001];
// Redraw in the new bounds
//[self setNeedsDisplayInRect:newFrame];
//[self performSelector:@selector(setNeedsDisplay) withObject:nil afterDelay:0.000001];

CGRect newRect = rect;
newRect.size.height = _textHeight;
CGContextClearRect(context, newRect);

CGContextRestoreGState(context);
//[self drawTextInRect:newRect withFont:self._font lineHeight:self._lineHeight inContext:context];
[self performSelector:@selector(setNeedsDisplay) withObject:nil afterDelay:0.000001];
//[self drawRect:newRect];

} else {
CGContextRestoreGState(context);

[super drawRect:rect];
}
CGContextRestoreGState(context);
[super drawRect:self.bounds];
}


Expand All @@ -494,7 +516,6 @@ - (void)dealloc {
[_fontColor release]; _fontColor = nil;
[_fontHighlightColor release], _fontHighlightColor = nil;
[_font release]; _font = nil;

[super dealloc];
}

Expand Down