Ios 如何使用UILabel和NSAttribute字符串垂直对齐文本

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

我正在使用UILabel和NSAttributedString设置IOS7中标签文本的行距。但是当我使用这个标签时,文本似乎没有在标签的中心对齐。下面是我设置标签文本(属性)的代码

-(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)