I have added one label in my nib file, then its required to have top-left alignment for that lable. As I am providing text at runtime so its not sure that how much lines there are. So if text contains only single line then it appears as vertical-center aligned. That alignment is not matching with my respective lable in front of it.
For example:
Which is looking odd :(
Is there any way where i can set label text proper to Top-Left alignment?
It's fairly easy to do. Create a UILabel
sublcass with a verticalAlignment
property and override textRectForBounds:limitedToNumberOfLines
to return the correct bounds for a top, middle or bottom vertical alignment. Here's the code:
SOLabel.h
#import <UIKit/UIKit.h>
typedef enum
{
VerticalAlignmentTop = 0, // default
VerticalAlignmentMiddle,
VerticalAlignmentBottom,
} VerticalAlignment;
@interface SOLabel : UILabel
@property (nonatomic, readwrite) VerticalAlignment verticalAlignment;
@end
SOLabel.m
@implementation SOLabel
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (!self) return nil;
// set inital value via IVAR so the setter isn't called
_verticalAlignment = VerticalAlignmentTop;
return self;
}
-(VerticalAlignment) verticalAlignment
{
return _verticalAlignment;
}
-(void) setVerticalAlignment:(VerticalAlignment)value
{
_verticalAlignment = value;
[self setNeedsDisplay];
}
// align text block according to vertical alignment settings
-(CGRect)textRectForBounds:(CGRect)bounds
limitedToNumberOfLines:(NSInteger)numberOfLines
{
CGRect rect = [super textRectForBounds:bounds
limitedToNumberOfLines:numberOfLines];
CGRect result;
switch (_verticalAlignment)
{
case VerticalAlignmentTop:
result = CGRectMake(bounds.origin.x, bounds.origin.y,
rect.size.width, rect.size.height);
break;
case VerticalAlignmentMiddle:
result = CGRectMake(bounds.origin.x,
bounds.origin.y + (bounds.size.height - rect.size.height) / 2,
rect.size.width, rect.size.height);
break;
case VerticalAlignmentBottom:
result = CGRectMake(bounds.origin.x,
bounds.origin.y + (bounds.size.height - rect.size.height),
rect.size.width, rect.size.height);
break;
default:
result = bounds;
break;
}
return result;
}
-(void)drawTextInRect:(CGRect)rect
{
CGRect r = [self textRectForBounds:rect
limitedToNumberOfLines:self.numberOfLines];
[super drawTextInRect:r];
}
@end