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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7192088/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:15:46  来源:igfitidea点击:

How to set top-left alignment for UILabel for iOS application?

iphoneioslabeluilabeltext-alignment

提问by Mrunal

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.

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

For example:

例如:

enter image description here

在此处输入图片说明

Which is looking odd :(

这看起来很奇怪:(

Is there any way where i can set label text proper to Top-Left alignment?

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

采纳答案by shawnwall

Rather than re-explaining, I will link to this rather extensive & highly rated question/answer:

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

Vertically align text to top within a UILabel

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

The short answer is no, Apple didn't make this easy, but it is possible by changing the frame size.

简短的回答是否定的,Apple 并没有让这变得容易,但可以通过更改框架大小来实现。

回答by memmons

It's fairly easy to do. Create a UILabelsublcass with a verticalAlignmentproperty and override textRectForBounds:limitedToNumberOfLinesto return the correct bounds for a top, middle or bottom vertical alignment. Here's the code:

这很容易做到。创建一个UILabel具有verticalAlignment属性和覆盖的子类,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

SOLabel.m

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

回答by A.G

I found a solution using AutoLayout in StoryBoard.

我在 StoryBoard 中使用 AutoLayout 找到了一个解决方案。

1) Set no of lines to 0 and text alignment to Left.

1) 将行数设置为 0,将文本对齐设置为左对齐。

enter image description here

在此处输入图片说明

2) Set height constraint.

2) 设置高度约束。

enter image description here

在此处输入图片说明

3) The height Constraint should be in Relation - Less Than or Equal

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

enter image description here

在此处输入图片说明

4)

4)

   override func viewWillLayoutSubviews() {
        sampleLabel.sizeToFit()
    }

I got the result as follows :

我得到的结果如下:

enter image description here

在此处输入图片说明

回答by totiG

The SOLabel works for me.

SOLabel 对我有用。

Swift 3 & 5:

斯威夫特 3 和 5:

This version has been updated from the original to allow support for RTL languages:

此版本已从原始版本更新,以支持 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)
    }
}

Swift 1:

斯威夫特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)
    }
}

回答by n13

In your code

在你的代码中

label.text = @"some text";
[label sizeToFit];

Beware that if you use that in table cells or other views that get recycled with different data, you'll need to store the original frame somewhere and reset it before calling sizeToFit.

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

回答by Mukesh Chapagain

In my case, it was bottom spaceconstraint issue. I had set it to = 16.

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

When I set it to bottom to >= 16, this issue got solved.

当我将它设置为 时bottom to >= 16,这个问题就解决了。

Also, if you have any height constraint in the label, then you need to remove it.

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

Here's my label's constraint view in the size inspector:

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

constraint

约束

回答by Maxim Zh

I found another solution for the same problem. I used UITextViewinstead of UILabeland switched editable()function to false.

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

回答by rharvey

I was also having this problem but what I found was the the order in which you set the UILabel's properties and methods matters!

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

If you call [label sizeToFit]before label.font = [UIFont fontWithName:@"Helvetica" size:14];then the text does not align to the top but if you swap them around then it does!

如果您[label sizeToFit]之前调用,label.font = [UIFont fontWithName:@"Helvetica" size:14];则文本不会与顶部对齐,但是如果您将它们交换,则它会对齐!

I also noticed that setting the text first makes a difference too.

我还注意到首先设置文本也会有所不同。

Hope this helps.

希望这可以帮助。

回答by TomG103

As you are using the interface builder, set the constraints for your label (be sure to set the height and width as well). Then in the Size Inspector, check the height for the label. There you will want it to read >= instead of =. Then in the implementation for that view controller, set the number of lines to 0 (can also be done in IB) and set the label [label sizeToFit]; and as your text gains length, the label will grow in height and keep your text in the upper left.

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

回答by Alejandro Camus

If what you need is non-editable text that by default starts at the top left corner you can simply use a Text View instead of a label and then set its state to non-editable, like this:

如果您需要的是默认从左上角开始的不可编辑文本,您可以简单地使用文本视图而不是标签,然后将其状态设置为不可编辑,如下所示:

textview.isEditable = false

Way easier than messing with the labels...

比弄乱标签容易得多......

Cheers!

干杯!