내 펜촉 파일에 레이블 하나를 추가 한 다음 해당 레이블에 대해 왼쪽 상단 정렬이 필요합니다. 런타임에 텍스트를 제공하므로 얼마나 많은 줄이 있는지 확실하지 않습니다. 따라서 텍스트에 한 줄만 포함되어 있으면 세로 중앙 정렬로 나타납니다. 그 정렬은 그 앞에있는 내 각 레이블과 일치하지 않습니다.
예를 들면 :

이상하게 보입니다 🙁
레이블 텍스트를 왼쪽 위 정렬에 맞게 설정할 수있는 방법이 있습니까?
답변
다시 설명하기보다는 다소 광범위하고 높은 등급의 질문 / 답변을 링크하겠습니다.
짧은 대답은 아니오입니다. Apple은 이것을 쉽게 만들지 않았지만 프레임 크기를 변경하면 가능합니다.
답변
매우 쉽습니다. 크리에이트 UILabelA를 sublcass 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
@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
답변
StoryBoard에서 AutoLayout을 사용하는 솔루션을 찾았습니다.
1) 줄 수를 0으로, 텍스트 정렬을 왼쪽으로 설정합니다.
2) 높이 제한을 설정합니다.
3) 높이 제약은 관계식이어야합니다-작거나 같음
4)
override func viewWillLayoutSubviews() {
sampleLabel.sizeToFit()
}
결과는 다음과 같습니다.
답변
SOLabel이 저에게 효과적입니다.
Swift 3 및 5 :
이 버전은 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)
}
}
스위프트 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)
}
}
답변
제 경우에는 bottom space제약 문제였습니다. 나는 그것을로 설정했다 = 16.
로 설정하면 bottom to >= 16이 문제가 해결되었습니다.
또한 레이블에 높이 제약이있는 경우이를 제거해야합니다.
크기 검사기에서 내 레이블의 제약보기는 다음과 같습니다.
답변
귀하의 코드에서
label.text = @"some text";
[label sizeToFit];
다른 데이터로 재활용되는 테이블 셀이나 다른 뷰에서이를 사용하는 경우 원본 프레임을 어딘가에 저장하고 sizeToFit을 호출하기 전에 재설정해야합니다.
답변
같은 문제에 대한 다른 해결책을 찾았습니다. UITextView대신 사용 UILabel하고 editable()기능을 false.





