diff --git a/.gitignore b/.gitignore index bb59993..20d4ce3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,17 @@ -# xcode noise -*.mode1v3 +# Xcode +.DS_Store +*/build/* *.pbxuser -*.perspective +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 *.perspectivev3 -*.pyc -*~.nib/ -build/* - -# Textmate - if you build your xcode projects with it -*.tm_build_errors - -# old skool -.svn - -# osx noise -.DS_Store +!default.perspectivev3 +xcuserdata profile +*.moved-aside +DerivedData +.idea/ +*.hmap \ No newline at end of file diff --git a/Default-568h@2x.png b/Default-568h@2x.png new file mode 100644 index 0000000..0891b7a Binary files /dev/null and b/Default-568h@2x.png differ diff --git a/MTLabel.xcodeproj/project.pbxproj b/MTLabel.xcodeproj/project.pbxproj index 07f9928..8186047 100644 --- a/MTLabel.xcodeproj/project.pbxproj +++ b/MTLabel.xcodeproj/project.pbxproj @@ -16,8 +16,9 @@ 147737E11391B7C200BCB59A /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 147737DF1391B7C200BCB59A /* MainWindow.xib */; }; 147737E41391B7C200BCB59A /* MTLabelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 147737E31391B7C200BCB59A /* MTLabelViewController.m */; }; 147737E71391B7C200BCB59A /* MTLabelViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 147737E51391B7C200BCB59A /* MTLabelViewController.xib */; }; - 147737EF1391B7D400BCB59A /* MTLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 147737EE1391B7D400BCB59A /* MTLabel.m */; }; + 147737EF1391B7D400BCB59A /* MTLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 147737EE1391B7D400BCB59A /* MTLabel.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 147737F11391B86600BCB59A /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 147737F01391B86600BCB59A /* CoreText.framework */; }; + FA614AF41727F8FC00724B20 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA614AF31727F8FC00724B20 /* Default-568h@2x.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -38,6 +39,7 @@ 147737ED1391B7D400BCB59A /* MTLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTLabel.h; sourceTree = ""; }; 147737EE1391B7D400BCB59A /* MTLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTLabel.m; sourceTree = ""; }; 147737F01391B86600BCB59A /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; }; + FA614AF31727F8FC00724B20 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -58,6 +60,7 @@ 147737BE1391B7C100BCB59A = { isa = PBXGroup; children = ( + FA614AF31727F8FC00724B20 /* Default-568h@2x.png */, 147737D31391B7C100BCB59A /* MTLabel */, 147737CC1391B7C100BCB59A /* Frameworks */, 147737CA1391B7C100BCB59A /* Products */, @@ -135,6 +138,9 @@ /* Begin PBXProject section */ 147737C01391B7C100BCB59A /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0460; + }; buildConfigurationList = 147737C31391B7C100BCB59A /* Build configuration list for PBXProject "MTLabel" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; @@ -160,6 +166,7 @@ 147737D81391B7C200BCB59A /* InfoPlist.strings in Resources */, 147737E11391B7C200BCB59A /* MainWindow.xib in Resources */, 147737E71391B7C200BCB59A /* MTLabelViewController.xib in Resources */, + FA614AF41727F8FC00724B20 /* Default-568h@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -247,7 +254,9 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "MTLabel/MTLabel-Prefix.pch"; + GCC_VERSION = ""; INFOPLIST_FILE = "MTLabel/MTLabel-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -260,7 +269,9 @@ COPY_PHASE_STRIP = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "MTLabel/MTLabel-Prefix.pch"; + GCC_VERSION = ""; INFOPLIST_FILE = "MTLabel/MTLabel-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; PRODUCT_NAME = "$(TARGET_NAME)"; VALIDATE_PRODUCT = YES; WRAPPER_EXTENSION = app; diff --git a/MTLabel/MTLabel.h b/MTLabel/MTLabel.h index b16dcb1..360ffda 100644 --- a/MTLabel/MTLabel.h +++ b/MTLabel/MTLabel.h @@ -17,6 +17,9 @@ // limitations under the License. #import + +@class HAWLabel; + @protocol MTLabelDelegate - (void)labelDidChangeFrame:(CGRect)frame; @end @@ -31,34 +34,21 @@ typedef enum { } MTLabelTextAlignment; -@interface MTLabel : UIView { - - int _numberOfLines; - CGFloat _lineHeight; - CGFloat _minimumFontSize; - NSString *_text; - UIColor *_fontColor, *_highlightColor; - UIFont *_font; - BOOL _limitToNumberOfLines; - BOOL _shouldResizeToFit; - MTLabelTextAlignment _textAlignment; - id delegate; - BOOL adjustSizeToFit; - -} +@interface MTLabel : UIView @property (nonatomic, readwrite, setter = setNumberOfLines:, getter = numberOfLines) int _numberOfLines; +@property (nonatomic, readwrite, setter = setMaxNumberOfLines:, getter = numberOfLines) int _maxNumberOfLines; @property (nonatomic, readwrite, setter = setLineHeight:, getter = lineHeight) CGFloat _lineHeight; @property (nonatomic, readonly) CGFloat _textHeight; @property (nonatomic, readwrite, setter = setMinimumFontSize:, getter = minimumFontSize) CGFloat _minimumFontSize; @property (nonatomic, retain, setter = setText:, getter = text) NSString *_text; -@property (nonatomic, retain, setter = setFontColor:, getter = fontColor) UIColor *_fontColor; +@property (nonatomic, retain, setter = setTextColor:, getter = fontColor) UIColor *_textColor; @property (nonatomic, retain, setter = setFontHighlightColor:, getter = fontHighlightColor) UIColor *_fontHighlightColor; @property (nonatomic, retain, setter = setFont:, getter = font) UIFont *_font; @property (nonatomic, readwrite, setter = setLimitToNumberOfLines:, getter = limitToNumberOfLines) BOOL _limitToNumberOfLines; @property (nonatomic, readwrite, setter = setResizeToFitText:, getter = resizeToFitText) BOOL _shouldResizeToFit; @property (nonatomic, readwrite, setter = setTextAlignment:, getter = textAlignment) MTLabelTextAlignment _textAlignment; -@property (nonatomic, assign) id delegate; +@property (nonatomic, weak) id delegate; @property (nonatomic, readwrite, setter = setAdjustSizeToFit:, getter = adjustSizeToFit) BOOL _adjustSizeToFit; @property (nonatomic, readwrite) CGFloat shadowOffset; @@ -85,5 +75,11 @@ typedef enum { -(BOOL)resizeToFitText; -(MTLabelTextAlignment)textAlignment; +- (CGFloat)labelBottomMargin; +- (CGFloat)labelTopMargin; +- (CGFloat)positionBelowLabel:(HAWLabel *)label offset:(CGSize)offset; +- (CGFloat)positionBelowView:(UIView *)view offset:(CGSize)offset; +- (CGFloat)positionBelowMTLabel:(MTLabel *)label offset:(CGSize)offset; +- (CGFloat)layoutHeight; @end diff --git a/MTLabel/MTLabel.m b/MTLabel/MTLabel.m index bbde323..e73cf7b 100644 --- a/MTLabel/MTLabel.m +++ b/MTLabel/MTLabel.m @@ -24,7 +24,7 @@ @interface MTLabel () --(void)drawTransparentBackground; +- (void)drawTransparentBackground; @end @@ -44,9 +44,9 @@ @implementation MTLabel @synthesize _text; @synthesize _lineHeight, _textHeight, _minimumFontSize; -@synthesize _numberOfLines; +@synthesize _numberOfLines, _maxNumberOfLines; @synthesize _font; -@synthesize _fontColor, _fontHighlightColor; +@synthesize _textColor, _fontHighlightColor; @synthesize _limitToNumberOfLines, _shouldResizeToFit; @synthesize _textAlignment; @synthesize delegate; @@ -56,107 +56,65 @@ @implementation MTLabel #pragma mark - Setters --(void)setNumberOfLines:(int)numberOfLines { - - +- (void)setNumberOfLines:(int)numberOfLines { if (numberOfLines != _numberOfLines) { - _numberOfLines = numberOfLines; [self setNeedsDisplay]; - } } --(void)setLineHeight:(CGFloat)lineHeight { - +- (void)setLineHeight:(CGFloat)lineHeight { if (lineHeight != _lineHeight) { - _lineHeight = lineHeight; [self setNeedsDisplay]; - } } --(void)setText:(NSString *)text { - +- (void)setText:(NSString *)text { if (text != _text) { - - if (_text) { - - [_text release]; - _text = nil; - } - - _text = [text retain]; + _text = text; [self setNeedsDisplay]; - } } --(void)setFont:(UIFont *)font { - +- (void)setFont:(UIFont *)font { if (font != _font) { - - if (_font) { - - [_font release]; - _font = nil; - - } - - _font = [font retain]; + _font = font; + + if (self._lineHeight == [UIFont systemFontOfSize:DEFAULT_FONT_SIZE].lineHeight) { self._lineHeight = _font.lineHeight; + + } [self setNeedsDisplay]; - } } --(void)setFontColor:(UIColor *)fontColor { - - if (fontColor != _fontColor) { - - if (_fontColor) { - - [_fontColor release]; - _fontColor = nil; - - } - - _fontColor = [fontColor retain]; +- (void)setFontColor:(UIColor *)fontColor { + if (fontColor != _textColor) { + _textColor = fontColor; [self setNeedsDisplay]; } } - (void)setFontHighlightColor:(UIColor *)fontHighlightColor { if (fontHighlightColor != _fontHighlightColor) { - if (_fontHighlightColor) { - [_fontHighlightColor release]; - _fontHighlightColor = nil; - } - _fontHighlightColor = [fontHighlightColor retain]; + _fontHighlightColor = fontHighlightColor; [self setNeedsDisplay]; } } --(void)setLimitToNumberOfLines:(BOOL)limitToNumberOfLines { - +- (void)setLimitToNumberOfLines:(BOOL)limitToNumberOfLines { if (_limitToNumberOfLines != limitToNumberOfLines) { - _limitToNumberOfLines = limitToNumberOfLines; [self setNeedsDisplay]; - } - } --(void)setResizeToFitText:(BOOL)resizeToFitText { - - +- (void)setResizeToFitText:(BOOL)resizeToFitText { if (_shouldResizeToFit != resizeToFitText) { - _shouldResizeToFit = resizeToFitText; [self setNeedsDisplay]; } @@ -164,15 +122,11 @@ -(void)setResizeToFitText:(BOOL)resizeToFitText { } --(void)setTextAlignment:(MTLabelTextAlignment)textAlignment { - +- (void)setTextAlignment:(MTLabelTextAlignment)textAlignment { if (_textAlignment != textAlignment) { - _textAlignment = textAlignment; [self setNeedsDisplay]; - } - } @@ -180,7 +134,7 @@ -(void)setTextAlignment:(MTLabelTextAlignment)textAlignment { -(NSString *)text { - + return _text; } @@ -203,7 +157,7 @@ -(int)numberOfLines { -(UIColor *)fontColor { - return _fontColor; + return _textColor; } -(BOOL)limitToNumberOfLines { @@ -227,10 +181,13 @@ - (void)setup { _textHeight = 0; self._font = [UIFont systemFontOfSize:DEFAULT_FONT_SIZE]; self._lineHeight = _font.lineHeight; - self._textAlignment = MTLabelTextAlignmentLeft; + self._textAlignment = MTLabelTextAlignmentLeft; + self.contentMode = UIViewContentModeRedraw; + self.contentStretch = CGRectMake(1, 1, 0, 0); + self.clipsToBounds = NO; [self setOpaque:NO]; } --(id)init { +- (id)init { self = [super init]; @@ -240,7 +197,7 @@ -(id)init { return self; } --(id)initWithFrame:(CGRect)frame { +- (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; @@ -268,7 +225,7 @@ - (id)initWithCoder:(NSCoder *)aDecoder { return self; } --(id)initWithText:(NSString *)text { +- (id)initWithText:(NSString *)text { self = [super init]; @@ -279,29 +236,29 @@ -(id)initWithText:(NSString *)text { return self; } -+(id)label { ++ (id)label { - return [[[MTLabel alloc] init] autorelease]; + return [[MTLabel alloc] init]; } -+(id)labelWithFrame:(CGRect)frame andText:(NSString *)text { ++ (id)labelWithFrame:(CGRect)frame andText:(NSString *)text { - return [[[MTLabel alloc] initWithFrame:frame andText:text] autorelease]; + return [[MTLabel alloc] initWithFrame:frame andText:text]; } -+(id)labelWithText:(NSString *)text { ++ (id)labelWithText:(NSString *)text { - return [[[MTLabel alloc] initWithText:text] autorelease]; + return [[MTLabel alloc] initWithText:text]; } #pragma mark - Drawing --(void)drawTransparentBackground { +- (void)drawTransparentBackground { [self setBackgroundColor:[UIColor clearColor]]; @@ -335,6 +292,46 @@ - (CGFloat)textOffsetForLine:(CTLineRef)line inRect:(CGRect)rect { return x; } + +- (CGSize)sizeThatFits:(CGSize)size +{ + if (_text == nil) { + return CGSizeMake(self.bounds.size.width, 0.0); + } + CGFloat height = 0.0; + BOOL hasMoreText = YES; + + CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)_font.fontName, _font.pointSize, NULL); + NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys: + (__bridge id)font, (id)kCTFontAttributeName, + _textColor.CGColor, kCTForegroundColorAttributeName, + nil]; + + NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:_text attributes:attributes]; + CFRelease(font); + + CTTypesetterRef typeSetter = CTTypesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attributedString); + CFIndex currentIndex = 0; + int lineCount = 0; + + while (hasMoreText) { + CFIndex lineLength = CTTypesetterSuggestLineBreak(typeSetter, + currentIndex, + self.bounds.size.width); + currentIndex += lineLength; + height += _lineHeight; + lineCount++; + + if (currentIndex >= [_text length] || (_limitToNumberOfLines && lineCount >= _maxNumberOfLines)) { + hasMoreText = NO; + } + } + + CFRelease(typeSetter); + + return CGSizeMake(self.bounds.size.width, height); +} + - (void)drawTextInRect:(CGRect)rect inContext:(CGContextRef)context { if (!_text) { @@ -342,36 +339,31 @@ - (void)drawTextInRect:(CGRect)rect inContext:(CGContextRef)context { } //Create a CoreText font object with name and size from the UIKit one - CTFontRef font = CTFontCreateWithName((CFStringRef)_font.fontName , - _font.pointSize, - NULL); + CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)_font.fontName, _font.pointSize, NULL); - //Setup the attributes dictionary with font and color NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys: - (id)font, (id)kCTFontAttributeName, - _fontColor.CGColor, kCTForegroundColorAttributeName, + (__bridge id)font, (id)kCTFontAttributeName, + _textColor.CGColor, kCTForegroundColorAttributeName, nil]; - NSAttributedString *attributedString = [[[NSAttributedString alloc] - initWithString:_text - attributes:attributes] autorelease]; + NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:_text attributes:attributes]; CFRelease(font); - //Create a TypeSetter object with the attributed text created earlier on - CTTypesetterRef typeSetter = CTTypesetterCreateWithAttributedString((CFAttributedStringRef)attributedString); + CTTypesetterRef typeSetter = CTTypesetterCreateWithAttributedString((__bridge 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; BOOL shouldDrawAlong = YES; - int count = 0; CFIndex currentIndex = 0; _textHeight = 0; + _numberOfLines = 0; //Start drawing lines until we run out of text while (shouldDrawAlong) { + _numberOfLines++; //Get CoreText to suggest a proper place to place the line break CFIndex lineLength = CTTypesetterSuggestLineBreak(typeSetter, @@ -382,7 +374,19 @@ - (void)drawTextInRect:(CGRect)rect inContext:(CGContextRef)context { CFRange lineRange = CFRangeMake(currentIndex, lineLength); CTLineRef line = CTTypesetterCreateLine(typeSetter, lineRange); - //Create a new CTLine if we want to justify the text + if (_limitToNumberOfLines && _numberOfLines >= _maxNumberOfLines && currentIndex < [_text length]-3) { + shouldDrawAlong = NO; + + CFAttributedStringRef truncationString = CFAttributedStringCreate(NULL, CFSTR("\u2026"), (__bridge CFDictionaryRef)attributes); + CTLineRef truncationToken = CTLineCreateWithAttributedString(truncationString); + CFRelease(truncationString); + + CTLineRef truncatedLine = CTLineCreateTruncatedLine(line, self.bounds.size.width-40, kCTLineTruncationEnd, truncationToken); + CFRelease(truncationToken); + CFRelease(line); line = nil; + + line = truncatedLine; + } if (_textAlignment == MTLabelTextAlignmentJustify) { CTLineRef justifiedLine = CTLineCreateJustifiedLine(line, 1.0, self.bounds.size.width); @@ -396,7 +400,7 @@ - (void)drawTextInRect:(CGRect)rect inContext:(CGContextRef)context { // 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 = CTLineGetTypographicBoundsAsRect(line, CGPointMake(x, y)); lineRect = CGRectIntegral(lineRect); lineRect = CGRectInset(lineRect, -1, -1); @@ -406,22 +410,14 @@ - (void)drawTextInRect:(CGRect)rect inContext:(CGContextRef)context { substring = [substring stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; if (0 < [substring length]) { - CGContextFillRect(context, lineRect); } } + //Setup the line position CGContextSetTextPosition(context, x, y); CTLineDraw(line, context); - - //Check to see if our index didn't exceed the text, and if should limit to number of lines - if ((currentIndex + lineLength >= [_text length]) && - !(_limitToNumberOfLines && count < _numberOfLines-1) ) { - shouldDrawAlong = NO; - - } - count++; CFRelease(line); CGFloat minFontSizeChange = 1; @@ -430,6 +426,10 @@ - (void)drawTextInRect:(CGRect)rect inContext:(CGContextRef)context { currentIndex += lineLength; _textHeight += _lineHeight; + if (currentIndex >= [_text length]) { + shouldDrawAlong = NO; + } + if (_adjustSizeToFit && _font.pointSize > _minimumFontSize) { if (self.bounds.size.height < _textHeight) { @@ -454,10 +454,8 @@ - (void)drawTextInRect:(CGRect)rect inContext:(CGContextRef)context { } CFRelease(typeSetter); - } - (void)drawRect:(CGRect)rect { - CGContextRef context = UIGraphicsGetCurrentContext(); //Grab the drawing context and flip it to prevent drawing upside-down @@ -466,42 +464,79 @@ - (void)drawRect:(CGRect)rect { CGContextScaleCTM(context, 1.0, -1.0); CGContextSaveGState(context); - - CGColorRef colorRef = CGColorCreate(CGColorSpaceCreateDeviceRGB(), CGColorGetComponents([_fontColor CGColor])); - CGContextSetShadowWithColor(context, CGSizeMake(self.shadowOffset, self.shadowOffset), 5, colorRef); - CGColorRelease(colorRef); [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)]; - - // Notify delegate that we did change frame - [delegate labelDidChangeFrame:self.frame]; + roundf(_textHeight))]; - // Ugly hack to avoid content being stretched - [self performSelector:@selector(setNeedsDisplay) withObject:nil afterDelay:0.0001]; + dispatch_async(dispatch_get_current_queue(), ^{ + [self setNeedsDisplay]; + }); } CGContextRestoreGState(context); [super drawRect:self.bounds]; } - #pragma mark - Memory managment - (void)dealloc { - [_text release]; _text = nil; - [_fontColor release]; _fontColor = nil; - [_fontHighlightColor release], _fontHighlightColor = nil; - [_font release]; _font = nil; - - [super dealloc]; +} + +#pragma mark - Fine positioning + +- (CGFloat)labelBottomMargin +{ + int lines = self.bounds.size.height / self.font.lineHeight; + if (lines > 1) + return -1.0 * self.font.descender + (self.font.lineHeight - self.font.pointSize); + else + return self.bounds.size.height - self.font.ascender; +} + +- (CGFloat)labelTopMargin +{ + return self.font.ascender - self.font.capHeight; +} + +- (CGFloat)positionBelowLabel:(MTLabel *)label offset:(CGSize)offset +{ + CGRect fromRect = label.frame; + CGRect toRect = self.bounds; + toRect.origin.x = fromRect.origin.x + offset.width; + toRect.origin.y = roundf(fromRect.origin.y + fromRect.size.height - label.labelBottomMargin + offset.height - self.labelTopMargin); + self.frame = toRect; + return roundf(CGRectGetMaxY(toRect) - self.labelBottomMargin); +} + +- (CGFloat)positionBelowView:(UIView *)view offset:(CGSize)offset +{ + CGRect fromRect = view.frame; + CGRect toRect = self.bounds; + toRect.origin.x = fromRect.origin.x + offset.width; + toRect.origin.y = roundf(fromRect.origin.y + fromRect.size.height + offset.height - self.labelTopMargin); + self.frame = toRect; + return roundf(CGRectGetMaxY(toRect) - self.labelBottomMargin); +} + +- (CGFloat)positionBelowMTLabel:(MTLabel *)label offset:(CGSize)offset +{ + CGRect fromRect = label.frame; + CGRect toRect = self.bounds; + toRect.origin.x = fromRect.origin.x + offset.width; + toRect.origin.y = roundf(fromRect.origin.y + fromRect.size.height - label.labelBottomMargin + offset.height - self.labelTopMargin); + self.frame = toRect; + return roundf(CGRectGetMaxY(toRect) - self.labelBottomMargin); +} + +- (CGFloat)layoutHeight +{ + return roundf(self.frame.size.height - self.labelBottomMargin - self.labelTopMargin); } @end