如何为iOS应用程序设置UILabel的左上角对齐方式?

Mru*_*nal 90 iphone label text-alignment uilabel ios

我在我的nib文件中添加了一个标签,然后需要对该标签进行左上角对齐.因为我在运行时提供文本所以它不确定有多少行.因此,如果文本仅包含单行,则它显示为垂直居中对齐.这种对齐方式与我前面的标签不匹配.

例如:

在此输入图像描述

哪个看起来很奇怪:(

有什么方法可以将标签文本设置为左上角对齐吗?

mem*_*ons 64

这很容易做到.创建UILabel具有verticalAlignment属性的sublcass 并覆盖textRectForBounds:limitedToNumberOfLines以返回顶部,中间或底部垂直对齐的正确边界.这是代码:

SOLabel.h

#import <UIKit/UIKit.h>

typedef enum
{
    VerticalAlignmentTop = 0, // default
    VerticalAlignmentMiddle,
    VerticalAlignmentBottom,
} VerticalAlignment;

@interface SOLabel : UILabel

   @property (nonatomic, readwrite) VerticalAlignment verticalAlignment;

@end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

  • 在运行这个之前,我还在SO上尝试了许多其他解决方案.它工作得很好!请记住,如果您在StoryBoard中执行此操作,请确保将CustomClass属性设置为SOLabel(或您决定命名的任何属性)而不是UILabel(在Utilities Inspector中). (3认同)

sha*_*all 61

我将链接到这个相当广泛和高度评价的问题/答案,而不是重新解释:

将文本垂直对齐到UILabel中的顶部

简短的回答是否定的,苹果公司并没有这么简单,但可以通过改变框架尺寸来实现.


A.G*_*A.G 42

我在StoryBoard中找到了使用AutoLayout的解决方案.

1)将行号设置为0,将文本对齐设置为左.

在此输入图像描述

2)设置高度约束.

在此输入图像描述

3)高度约束应该是关系 - 小于或等于

在此输入图像描述

4)

   override func viewWillLayoutSubviews() {
        sampleLabel.sizeToFit()
    }
Run Code Online (Sandbox Code Playgroud)

我得到的结果如下:

在此输入图像描述

  • 就像魅力一样,即使在重用的UITableViewCell中也是如此. (2认同)

tot*_*tiG 39

SOLabel为我工作.

斯威夫特1:

class UIVerticalAlignLabel: UILabel {

enum VerticalAlignment : Int {
    case VerticalAlignmentTop = 0
    case VerticalAlignmentMiddle = 1
    case VerticalAlignmentBottom = 2
}

var verticalAlignment : VerticalAlignment = .VerticalAlignmentTop {
    didSet {
        setNeedsDisplay()
    }
}

required init(coder aDecoder: NSCoder){
    super.init(coder: aDecoder)
}

override func textRectForBounds(bounds: CGRect, limitedToNumberOfLines: Int) -> CGRect {
    let rect = super.textRectForBounds(bounds, limitedToNumberOfLines: limitedToNumberOfLines)

    switch(verticalAlignment) {
        case .VerticalAlignmentTop:
            return CGRectMake(bounds.origin.x, bounds.origin.y, rect.size.width, rect.size.height)
        case .VerticalAlignmentMiddle:
            return CGRectMake(bounds.origin.x, bounds.origin.y + (bounds.size.height - rect.size.height) / 2, rect.size.width, rect.size.height)
        case .VerticalAlignmentBottom:
            return CGRectMake(bounds.origin.x, bounds.origin.y + (bounds.size.height - rect.size.height), rect.size.width, rect.size.height)
        default:
            return bounds
    }
}

override func drawTextInRect(rect: CGRect) {
    let r = self.textRectForBounds(rect, limitedToNumberOfLines: self.numberOfLines)
    super.drawTextInRect(r)
    }
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特3:

此版本已从原始版本更新,以支持RTL语言:

public class VerticalAlignLabel: UILabel {
    enum VerticalAlignment {
        case top
        case middle
        case bottom
    }

    var verticalAlignment : VerticalAlignment = .top {
        didSet {
            setNeedsDisplay()
        }
    }

    override public func textRect(forBounds bounds: CGRect, limitedToNumberOfLines: Int) -> CGRect {
        let rect = super.textRect(forBounds: bounds, limitedToNumberOfLines: limitedToNumberOfLines)

        if UIView.userInterfaceLayoutDirection(for: .unspecified) == .rightToLeft {
            switch verticalAlignment {
            case .top:
                return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
            case .middle:
                return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y + (bounds.size.height - rect.size.height) / 2, width: rect.size.width, height: rect.size.height)
            case .bottom:
                return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y + (bounds.size.height - rect.size.height), width: rect.size.width, height: rect.size.height)
            }
        } else {
            switch verticalAlignment {
            case .top:
                return CGRect(x: bounds.origin.x, y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
            case .middle:
                return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height) / 2, width: rect.size.width, height: rect.size.height)
            case .bottom:
                return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height), width: rect.size.width, height: rect.size.height)
            }
        }
    }

    override public func drawText(in rect: CGRect) {
        let r = self.textRect(forBounds: rect, limitedToNumberOfLines: self.numberOfLines)
        super.drawText(in: r)
    }
}
Run Code Online (Sandbox Code Playgroud)


n13*_*n13 13

在你的代码中

label.text = @"some text";
[label sizeToFit];
Run Code Online (Sandbox Code Playgroud)

请注意,如果您在表单元格或其他使用不同数据回收的视图中使用它,则需要将原始帧存储在某处并在调用sizeToFit之前重置它.


小智 8

我找到了同样问题的另一种解决方案.我使用UITextView而不是UILabel和切换editable()功能false.

  • 这是一个愚蠢的黑客攻击,在最坏的情况下对未来的开发者有误导性...... (3认同)

rha*_*vey 6

我也遇到了这个问题,但我发现你设置UILabel属性和方法的顺序很重要!

如果你[label sizeToFit]之前打电话label.font = [UIFont fontWithName:@"Helvetica" size:14];,文字没有对齐到顶部,但是如果你交换它们就可以了!

我还注意到,首先设置文本也会产生影响.

希望这可以帮助.


Muk*_*ain 6

就我而言,这是bottom space约束问题。我已将其设置为= 16

当我将其设置为时bottom to >= 16,此问题已解决。

另外,如果标签中有任何高度限制,则需要将其删除。

这是尺寸检查器中标签的约束视图:

约束


Tom*_*103 5

当您使用界面生成器时,请设置标签的约束(请务必设置高度和宽度)。然后在尺寸检查器中,检查标签的高度。在那里,您将希望它读取 >= 而不是 =。然后在该视图控制器的实现中,将行数设置为0(也可以在IB中完成)并设置标签[label sizeToFit];随着文本长度的增加,标签的高度也会增加,并使文本保持在左上角。