Ios 如何使用UILabel和NSAttribute字符串垂直对齐文本
我正在使用UILabel和NSAttributedString设置IOS7中标签文本的行距。但是当我使用这个标签时,文本似乎没有在标签的中心对齐。下面是我设置标签文本(属性)的代码Ios 如何使用UILabel和NSAttribute字符串垂直对齐文本,ios,objective-c,uilabel,nsattributedstring,Ios,Objective C,Uilabel,Nsattributedstring,我正在使用UILabel和NSAttributedString设置IOS7中标签文本的行距。但是当我使用这个标签时,文本似乎没有在标签的中心对齐。下面是我设置标签文本(属性)的代码 -(void)setText:(NSString *)text { [super setText:text]; if(text) [self setLineSpace]; } -(void)setLineSpace { if([[[UIDevice currentDevice
-(void)setText:(NSString *)text
{
[super setText:text];
if(text)
[self setLineSpace];
}
-(void)setLineSpace
{
if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7)
{
NSMutableAttributedString *string=[[NSMutableAttributedString alloc]initWithString:self.text];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.alignment=NSTextAlignmentJustified;
[paragraphStyle setLineSpacing:4] ;
// paragraphStyle.minimumLineHeight =0;
// paragraphStyle.maximumLineHeight=7;
// CTTextAlignment alignment = kCTCenterTextAlignment;
[string addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, string.length)];
self.text=nil;
self.attributedText=string;
[self setBackgroundColor:[UIColor redColor]];
}
}
下面是一些截图,顺便说一句,我将UILabel子类化为并覆盖setter以实现行间距
您可以使用其他解决方法-自定义UILabel NWLabel.m
#import "NWLabel.h"
@implementation NWLabel
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (!self) return nil;
_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];
}
NWLabel.h
#import <UIKit/UIKit.h>
typedef enum
{
VerticalAlignmentTop = 0, // default
VerticalAlignmentMiddle,
VerticalAlignmentBottom,
} VerticalAlignment;
@interface NWLabel : UILabel
{
@private VerticalAlignment _verticalAlignment;
}
@property (nonatomic, readwrite, assign) VerticalAlignment verticalAlignment;
@end
#导入
类型定义枚举
{
VerticalAlignmentTop=0,//默认值
垂直排列中间,
垂直对齐底部,
}垂直排列;
@接口NWLabel:UILabel
{
@私人垂直对齐(u垂直对齐);;
}
@属性(非原子、读写、赋值)垂直对齐垂直对齐;
@结束
也许你不能用简单的方式使用UILabel
如果可能,可以使用UITextField垂直对齐内容
否则,使用NSAttributedString和标签文本,您可以调整行高(不确定)。当自定义标签中只显示一行文本时,不要设置行距 实际上我解决了它……:)。问题在于我使用的自定义字体 进行了一些研发,但现在它似乎起作用了 刚刚为label创建了一个子类,并覆盖了一些默认方法
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines
{
CGRect textRect = [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
if(([self.font.fontName isEqualToString:@"Gotham"]||[self.font.fontName isEqualToString:@"Gotham-Bold"]||[self.font.fontName isEqualToString:@"Gotham-Medium"])&&((int)[[[UIDevice currentDevice] systemVersion] floatValue])==6&&self.verticalAlignment==AlignMiddle)
{
textRect.origin.y = bounds.origin.y + (bounds.size.height - textRect.size.height) / 2.0;
return [self addToRect:textRect x:0 y:2];
}
return [self addToRect:textRect x:0 y:0.5];
}
-(void)drawTextInRect:(CGRect)requestedRect
{
if(((int)[[[UIDevice currentDevice] systemVersion] floatValue])>=7)
[super drawTextInRect:[self addToRect:requestedRect x:0 y:0.5]];
else
{
CGRect actualRect = [self textRectForBounds:requestedRect limitedToNumberOfLines:self.numberOfLines];
[super drawTextInRect:actualRect];
}
}
-(CGRect)addToRect:(CGRect)rect x:(CGFloat)dx y:(CGFloat) dy
{
rect=CGRectMake(rect.origin.x+dx, rect.origin.y+dy, rect.size.width, rect.size.height);
return rect;
}
-(CGRect)makeRect:(CGRect)rect x:(CGFloat)dx y:(CGFloat) dy
{
rect=CGRectMake(dx,dy, rect.size.width+dx, rect.size.height+dy);
return rect;
}
-(CGRect)makeRects:(CGRect)rect x:(CGFloat)dx y:(CGFloat) dy
{
rect=CGRectMake(rect.origin.x,rect.origin.y, rect.size.width+dx, rect.size.height+dy);
return rect;
}
-(void)truncateToFit
{
if([[[UIDevice currentDevice] systemVersion] floatValue] < 7)
{
[self sizeToFit];
CGRect frame=self.frame;
if(frame.size.height<self.frame.size.height)
self.frame=[self makeRects:frame x:0 y:0.5];
}
else
{
self.frame=[self makeRects:self.frame x:0 y:0.5];
[self sizeToFit];
}
}
-(void)truncatesToFit
{
self.lineBreakMode=NSLineBreakByTruncatingTail;
self.numberOfLines=2;
[self sizeToFit];
self.frame=[self makeRects:self.frame x:0 y:0.5];
}
-(void)truncatesToFit:(NSInteger )linesCount
{
self.numberOfLines=linesCount;
[self sizeToFit];
self.frame=[self makeRects:self.frame x:0 y:0.5];
}
-(CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines
{
CGRect textRect=[super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
如果([self.font.fontName isEqualToString:@“Gotham”]|[self.font.fontName isEqualToString:@“Gotham Bold”]|[self.font.fontName isEqualToString:@“Gotham Medium”])和((int)[[UIDevice currentDevice systemVersion]floatValue])=6&&self verticalAlignment==AlignMiddle)
{
textRect.origin.y=bounds.origin.y+(bounds.size.height-textRect.size.height)/2.0;
return[self addToRect:textRect x:0 y:2];
}
return[self addToRect:textRect x:0 y:0.5];
}
-(void)drawTextInRect:(cRect)requestedRect
{
如果(((int)[[UIDevice currentDevice]systemVersion]floatValue])>=7)
[super drawTextInRect:[self-addToRect:requestedRect x:0 y:0.5];
其他的
{
CGRect ACTIVALRECT=[self-textRectForBounds:requestedRect limitedToNumberOfLines:self.numberOfLines];
[超级drawTextInRect:actualRect];
}
}
-(CGRect)addToRect:(CGRect)rect x:(CGFloat)dx y:(CGFloat)dy
{
rect=CGRectMake(rect.origin.x+dx,rect.origin.y+dy,rect.size.width,rect.size.height);
返回矩形;
}
-(CGRect)makeRect:(CGRect)rect x:(CGFloat)dx y:(CGFloat)dy
{
rect=CGRectMake(dx,dy,rect.size.width+dx,rect.size.height+dy);
返回矩形;
}
-(CGRect)makeRects:(CGRect)rect x:(CGFloat)dx y:(CGFloat)dy
{
rect=CGRectMake(rect.origin.x,rect.origin.y,rect.size.width+dx,rect.size.height+dy);
返回矩形;
}
-(无效)截短配合
{
如果([[[UIDevice currentDevice]系统版本]浮点值]<7)
{
[自我尺寸匹配];
CGRect frame=self.frame;
if(frame.size.height可通过属性字符串完成:
ObjC:
斯威夫特:
// shift the text up 10 pixels
string.addAttributes([NSAttributedStringKey.baselineOffset:10], range: range)
将Ivan M in提出的解决方案转换为Swift 5
class VerticallyAlignedUILabel:UILabel{
枚举垂直对齐{
箱盖
箱底
中间格
}
公共垂直对齐:垂直对齐{
迪塞特{
self.setNeedsDisplay()
}
}
init(帧:CGRect,垂直对齐:垂直对齐=.middle){
自垂直对齐=垂直对齐
super.init(frame:frame)
}
必需初始化?(编码器:NSCoder){
fatalError(“初始化(编码者:)尚未实现”)
}
重写func textRect(forBounds bounds:CGRect,LIMITEDTONMBEROFLINES numberOfLines:Int)->CGRect{
var textRect:CGRect=super.textRect(forBounds:bounds,limitedToNumberOfLines:numberOfLines)
开关自垂直对齐{
案例顶部:
textRect.origin.y=bounds.origin.y
案例底部:
textRect.origin.y=bounds.origin.y+bounds.size.height-textRect.size.height
案例.中间:
textRect.origin.y=bounds.origin.y+(bounds.size.height-textRect.size.height)/2.0
}
返回textRect
}
重写func drawText(在rect:CGRect中){
让actualRect=self.textRect(forBounds:rect,limitedToNumberOfLines:self.numberOfLines)
super.drawText(in:actualRect)
}
}
@preetam我想真正对齐字符串..看截图新闻更符合标签的“上一部分”。您只需要UILabel,我的意思是如果您可以使用UITextField,那么在xib中它提供了控制部分,您可以直接更改文本的对齐方式,而无需写入code@hussainShabbir文本视图不是一个选项n对我来说,我需要UILabel如果你的标签只显示一行文本,为什么你需要担心行距?或者文本的其余部分不可见?你的问题与此相关,这也不起作用,而且我必须手动编写水平对齐的代码。原始答案由@ivan.m.发布。不幸的是,我需要行距ios 7没有纽约市的行距(默认值),因此我需要手动提供该行距(
// shift the text up 10 pixels
string.addAttributes([NSAttributedStringKey.baselineOffset:10], range: range)