繁体   English   中英

如何使用 UILabel 和 NSAttributedString 垂直对齐文本

[英]How to Vertically Align Text Using UILabel and NSAttributedString

我正在使用 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 以实现行间距。

在此处输入图片说明

实际上我解决了它....:) :) 问题出在我使用的自定义字体上。

进行了一些研发,但现在似乎奏效了

刚刚为标签创建了一个子类并覆盖了一些默认方法。

- (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];

}

可能您无法以简单的方式使用 UILabel 做到这一点。

如果可能,您可以使用 UITextField 垂直对齐内容。

否则使用 NSAttributedString 和标签文本,您可以调整 Line-Height (不确定)。

可以通过属性字符串完成:

对象:

// shift the text down 10 pixels
[string addAttribute:NSBaselineOffsetAttributeName value:@(-10) range:NSMakeRange(0, string.length)];

斯威夫特:

// shift the text up 10 pixels
string.addAttributes([NSAttributedStringKey.baselineOffset:10], range: range)

您可以使用其他一些解决方法 - 自定义 UILabel

标签文件

#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];
}

标签文件

#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

当您的自定义标签中只显示一行文本时,请不要设置行距。

将 Ivan M 在https://discussions.apple.com/thread/1759957?tstart=0 中提出的解决方案转换为 Swift 5

class VerticallyAlignedUILabel: UILabel {
    enum VerticalAlignment {
        case top
        case bottom
        case middle
    }

    public var verticalAlignment:VerticalAlignment {
        didSet {
            self.setNeedsDisplay()
        }
    }

    init(frame: CGRect, verticalAlignment:VerticalAlignment = .middle) {
        self.verticalAlignment = verticalAlignment
        super.init(frame: frame)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
        var textRect:CGRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)

        switch self.verticalAlignment {
        case .top:
            textRect.origin.y = bounds.origin.y
        case .bottom:
            textRect.origin.y = bounds.origin.y + bounds.size.height - textRect.size.height
        case .middle:
            textRect.origin.y = bounds.origin.y + (bounds.size.height - textRect.size.height) / 2.0
        }

        return textRect
    }

    override func drawText(in rect: CGRect) {
        let actualRect = self.textRect(forBounds: rect, limitedToNumberOfLines: self.numberOfLines)
        super.drawText(in: actualRect)
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM