如何为 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
How to set top-left alignment for UILabel for iOS application?
提问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:
例如:
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
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 UILabel
sublcass with a verticalAlignment
property and override textRectForBounds:limitedToNumberOfLines
to 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,将文本对齐设置为左对齐。
2) Set height constraint.
2) 设置高度约束。
3) The height Constraint should be in Relation - Less Than or Equal
3)高度约束应该是相关的 - 小于或等于
4)
4)
override func viewWillLayoutSubviews() {
sampleLabel.sizeToFit()
}
I got the result as follows :
我得到的结果如下:
回答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 space
constraint 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:
这是我的标签在尺寸检查器中的约束视图:
回答by Maxim Zh
I found another solution for the same problem. I used UITextView
instead of UILabel
and switched editable()
function to false
.
我为同样的问题找到了另一种解决方案。我使用UITextView
而不是UILabel
将editable()
功能切换到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!
干杯!