回答:
垂直方向の配置を設定する方法はありません UILabel
んが、ラベルのフレームを変更することで同じ効果を得ることができます。ラベルをオレンジにして、何が起こっているのかはっきりとわかるようにしています。
これをすばやく簡単に行う方法は次のとおりです。
[myLabel sizeToFit];
複数の行を作成する長いテキストのラベルがある場合は、に設定numberOfLines
します0
(ここでのゼロは、無制限の行数を意味します)。
myLabel.numberOfLines = 0;
[myLabel sizeToFit];
長いバージョン
何が起こっているかを確認できるように、コードでラベルを作成します。このほとんどは、Interface Builderでも設定できます。私の設定は、余白(20ポイント)を表示するためにPhotoshopで作成した背景画像を含むビューベースのアプリです。ラベルは魅力的なオレンジ色なので、寸法で何が起こっているかを確認できます。
- (void)viewDidLoad
{
[super viewDidLoad];
// 20 point top and left margin. Sized to leave 20 pt at right.
CGRect labelFrame = CGRectMake(20, 20, 280, 150);
UILabel *myLabel = [[UILabel alloc] initWithFrame:labelFrame];
[myLabel setBackgroundColor:[UIColor orangeColor]];
NSString *labelText = @"I am the very model of a modern Major-General, I've information vegetable, animal, and mineral";
[myLabel setText:labelText];
// Tell the label to use an unlimited number of lines
[myLabel setNumberOfLines:0];
[myLabel sizeToFit];
[self.view addSubview:myLabel];
}
sizeToFit
中央揃えまたは右揃えのテキストでは、使用に関するいくつかの制限が関係します。ここで何が起こるかです:
// myLabel.textAlignment = NSTextAlignmentRight;
myLabel.textAlignment = NSTextAlignmentCenter;
[myLabel setNumberOfLines:0];
[myLabel sizeToFit];
ラベルのサイズは、左上隅が固定されたままです。元のラベルの幅を変数に保存してに設定するsizeToFit
か、固定幅を指定してこれらの問題に対抗できます。
myLabel.textAlignment = NSTextAlignmentCenter;
[myLabel setNumberOfLines:0];
[myLabel sizeToFit];
CGRect myFrame = myLabel.frame;
// Resize the frame's width to 280 (320 - margins)
// width could also be myOriginalLabelFrame.size.width
myFrame = CGRectMake(myFrame.origin.x, myFrame.origin.y, 280, myFrame.size.height);
myLabel.frame = myFrame;
sizeToFit
最初のラベルの最小幅が尊重されることに注意してください。幅100のラベルから始めてsizeToFit
それを呼び出すと、幅が100(または少し少ない)の(おそらく非常に高い)ラベルが返されます。サイズを変更する前に、ラベルを必要な最小幅に設定することをお勧めします。
その他の注意事項:
lineBreakMode
尊重されるかどうかは、それがどのように設定されているかによって異なります。NSLineBreakByTruncatingTail
(デフォルト)はsizeToFit
、他の2つの切り捨てモード(ヘッドとミドル)と同様に、後に無視されます。NSLineBreakByClipping
も無視されます。NSLineBreakByCharWrapping
通常どおり機能します。フレーム幅は、右端の文字に合わせて狭められています。
Mark Ameryがコメントで自動レイアウトを使用してNIBとストーリーボードを修正しました:
view
autolayoutを使用するViewControllerのサブビューとしてラベルがnibまたはストーリーボードに含まれている場合、autolayoutが呼び出されてサブビューが配置sizeToFit
さviewDidLoad
れるので、呼び出しは機能しませんviewDidLoad
。sizeToFit
コール。ただし、sizeToFit
内部からの呼び出しviewDidLayoutSubviews
は機能します。
これは、NSString
メソッドsizeWithFont:constrainedToSize:lineBreakMode:
を使用して文字列を合わせるために必要なフレームの高さを計算し、次に原点と幅を設定します。
挿入するテキストを使用して、ラベルのフレームのサイズを変更します。これにより、任意の数の行に対応できます。
CGSize maximumSize = CGSizeMake(300, 9999);
NSString *dateString = @"The date today is January 1st, 1999";
UIFont *dateFont = [UIFont fontWithName:@"Helvetica" size:14];
CGSize dateStringSize = [dateString sizeWithFont:dateFont
constrainedToSize:maximumSize
lineBreakMode:self.dateLabel.lineBreakMode];
CGRect dateFrame = CGRectMake(10, 10, 300, dateStringSize.height);
self.dateLabel.frame = dateFrame;
adjustsFontSizeToFitWidth
使用する必要がある場合は、sizeToFitを使用してから、ラベルのフレームを0、0、theWidthYouWant、label.frame.size.height(sizeToFitによって決定される新しい高さ)に設定します。次に適用しますadjustsFontSizeToFitWidth
新しいテキストを設定します。
myLabel.text = @"Some Text"
maximum number
行数を0(自動)に設定します。
myLabel.numberOfLines = 0
ラベルのフレームを最大サイズに設定します。
myLabel.frame = CGRectMake(20,20,200,800)
sizeToFit
フレームサイズを小さくして、内容がちょうど収まるように呼び出します。
[myLabel sizeToFit]
ラベルフレームは、テキストに合わせて十分な高さと幅になりました。左上は変更しないでください。これを左上揃えのテキストでのみテストしました。他の配置では、後でフレームを変更する必要がある場合があります。
また、私のラベルでは折り返しが有効になっています。
拡張ソリューションを参照する:
for(int i=1; i< newLinesToPad; i++)
self.text = [self.text stringByAppendingString:@"\n"];
に置き換える必要があります
for(int i=0; i<newLinesToPad; i++)
self.text = [self.text stringByAppendingString:@"\n "];
iPhone UILabels
の末尾のキャリッジリターンは無視されるため、追加された改行ごとに追加のスペースが必要です:(
同様に、alignBottomも@" \n@%"
、"\n@%"
する必要があります(サイクルの初期化は「for(int i = 0 ...」にも置き換える必要があります)。
次の拡張機能は私にとってはうまくいきます:
// -- file: UILabel+VerticalAlign.h
#pragma mark VerticalAlign
@interface UILabel (VerticalAlign)
- (void)alignTop;
- (void)alignBottom;
@end
// -- file: UILabel+VerticalAlign.m
@implementation UILabel (VerticalAlign)
- (void)alignTop {
CGSize fontSize = [self.text sizeWithFont:self.font];
double finalHeight = fontSize.height * self.numberOfLines;
double finalWidth = self.frame.size.width; //expected width of label
CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
int newLinesToPad = (finalHeight - theStringSize.height) / fontSize.height;
for(int i=0; i<newLinesToPad; i++)
self.text = [self.text stringByAppendingString:@"\n "];
}
- (void)alignBottom {
CGSize fontSize = [self.text sizeWithFont:self.font];
double finalHeight = fontSize.height * self.numberOfLines;
double finalWidth = self.frame.size.width; //expected width of label
CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
int newLinesToPad = (finalHeight - theStringSize.height) / fontSize.height;
for(int i=0; i<newLinesToPad; i++)
self.text = [NSString stringWithFormat:@" \n%@",self.text];
}
@end
次に、各yourLabelテキスト割り当ての後に、[yourLabel alignTop];
または[yourLabel alignBottom];
を呼び出します。
VerticalAlign
後の括弧の間に追加していることに気付きました@implementation UILabel
。Objective-Cが初めてなので、この構文に出会ったことはありません。これは何と呼ばれていますか?
sizeWithFont:constrainedToSize:lineBreakMode:
とsizeWithFont:はどちらもiOS7では廃止されています。numberOfLinesが0より大きい場合にも、このカテゴリは、ラベルだけで動作します
誰かの助けになった場合のために、私は同じ問題を抱えていましたが、使用から使用UILabel
に切り替えるだけで問題を解決することができましたUITextView
。機能が少し異なるので、これがすべての人に適しているわけではないことに感謝します。
を使用するように切り替える場合はUITextView
、すべてのスクロールビューのプロパティとユーザー操作を有効にしてオフにすることができます。これにより、ラベルのように機能するように強制できます。
UITextView
を使用すると、すぐに望ましい結果が得られました。
ムスも大騒ぎもない
@interface MFTopAlignedLabel : UILabel
@end
@implementation MFTopAlignedLabel
- (void)drawTextInRect:(CGRect) rect
{
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:self.text attributes:@{NSFontAttributeName:self.font}];
rect.size.height = [attributedText boundingRectWithSize:rect.size
options:NSStringDrawingUsesLineFragmentOrigin
context:nil].size.height;
if (self.numberOfLines != 0) {
rect.size.height = MIN(rect.size.height, self.numberOfLines * self.font.lineHeight);
}
[super drawTextInRect:rect];
}
@end
ムスも、Objective-cも、大騒ぎもなし、Swift 3:
class VerticalTopAlignLabel: UILabel {
override func drawText(in rect:CGRect) {
guard let labelText = text else { return super.drawText(in: rect) }
let attributedText = NSAttributedString(string: labelText, attributes: [NSFontAttributeName: font])
var newRect = rect
newRect.size.height = attributedText.boundingRect(with: rect.size, options: .usesLineFragmentOrigin, context: nil).size.height
if numberOfLines != 0 {
newRect.size.height = min(newRect.size.height, CGFloat(numberOfLines) * font.lineHeight)
}
super.drawText(in: newRect)
}
}
Swift 4.2
class VerticalTopAlignLabel: UILabel {
override func drawText(in rect:CGRect) {
guard let labelText = text else { return super.drawText(in: rect) }
let attributedText = NSAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: font])
var newRect = rect
newRect.size.height = attributedText.boundingRect(with: rect.size, options: .usesLineFragmentOrigin, context: nil).size.height
if numberOfLines != 0 {
newRect.size.height = min(newRect.size.height, CGFloat(numberOfLines) * font.lineHeight)
}
super.drawText(in: newRect)
}
}
上記の答えのように、しかしそれは完全に正しくなかったか、コードに平手打ちするのは簡単ではなかったので、私はそれを少し片付けました。この拡張子を独自の.hおよび.mファイルに追加するか、使用する実装のすぐ上に貼り付けます。
#pragma mark VerticalAlign
@interface UILabel (VerticalAlign)
- (void)alignTop;
- (void)alignBottom;
@end
@implementation UILabel (VerticalAlign)
- (void)alignTop
{
CGSize fontSize = [self.text sizeWithFont:self.font];
double finalHeight = fontSize.height * self.numberOfLines;
double finalWidth = self.frame.size.width; //expected width of label
CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
int newLinesToPad = (finalHeight - theStringSize.height) / fontSize.height;
for(int i=0; i<= newLinesToPad; i++)
{
self.text = [self.text stringByAppendingString:@" \n"];
}
}
- (void)alignBottom
{
CGSize fontSize = [self.text sizeWithFont:self.font];
double finalHeight = fontSize.height * self.numberOfLines;
double finalWidth = self.frame.size.width; //expected width of label
CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
int newLinesToPad = (finalHeight - theStringSize.height) / fontSize.height;
for(int i=0; i< newLinesToPad; i++)
{
self.text = [NSString stringWithFormat:@" \n%@",self.text];
}
}
@end
そして、使用するには、テキストをラベルに入れ、適切なメソッドを呼び出して位置合わせします。
[myLabel alignTop];
または
[myLabel alignBottom];
これを達成するためのさらに迅速な(そしてダーティーな)方法は、UILabelの改行モードを「クリップ」に設定し、固定量の改行を追加することです。
myLabel.lineBreakMode = UILineBreakModeClip;
myLabel.text = [displayString stringByAppendingString:"\n\n\n\n"];
この解決策は誰にとっても機能しません。特に、文字列の最後に「...」を表示したい場合は、表示している行数を超える場合は、次のいずれかを使用する必要があります。コードのより長いビット-しかし多くの場合、これはあなたが必要とするものを手に入れるでしょう。
UILineBreakModeWordWrap
代わりに使用してください。
ストーリーボードを使用する最も簡単な方法:
StackViewにラベルを埋め込む、属性インスペクターでStackViewの次の2つの属性を設定します。
の1- Axis
へHorizontal
、
2 Alignment
からTop
UILabel
一部のUIView
サブクラスに配置し(UIView
通常はプレーンで十分です)、そのラベルを下方向に拡張することをお勧めします。ありがとう!
UILabel
とStackViewはその仕事をやらせます。ありがとう!
代わりに、垂直方向の配置オプションを持つwhichをUILabel
使用UITextField
できます。
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
textField.userInteractionEnabled = NO; // Don't allow interaction
私はこれに長い間取り組んできましたが、自分の解決策を共有したいと思いました。
これにより、UILabel
テキストを0.5スケールまで自動縮小し、テキストを垂直方向に中央揃えにします。これらのオプションは、ストーリーボード/ IBでも使用できます。
[labelObject setMinimumScaleFactor:0.5];
[labelObject setBaselineAdjustment:UIBaselineAdjustmentAlignCenters];
新しいクラスを作成する
LabelTopAlign
.hファイル
#import <UIKit/UIKit.h>
@interface KwLabelTopAlign : UILabel {
}
@end
.mファイル
#import "KwLabelTopAlign.h"
@implementation KwLabelTopAlign
- (void)drawTextInRect:(CGRect)rect {
int lineHeight = [@"IglL" sizeWithFont:self.font constrainedToSize:CGSizeMake(rect.size.width, 9999.0f)].height;
if(rect.size.height >= lineHeight) {
int textHeight = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(rect.size.width, rect.size.height)].height;
int yMax = textHeight;
if (self.numberOfLines > 0) {
yMax = MIN(lineHeight*self.numberOfLines, yMax);
}
[super drawTextInRect:CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, yMax)];
}
}
@end
同じことを行う、より簡単な実装を次に示します。
#import "KwLabelTopAlign.h"
@implementation KwLabelTopAlign
- (void)drawTextInRect:(CGRect)rect
{
CGFloat height = [self.text sizeWithFont:self.font
constrainedToSize:rect.size
lineBreakMode:self.lineBreakMode].height;
if (self.numberOfLines != 0) {
height = MIN(height, self.font.lineHeight * self.numberOfLines);
}
rect.size.height = MIN(rect.size.height, height);
[super drawTextInRect:rect];
}
@end
sizeToFit
ソリューションとは異なり、これは実際には短いテキストを長いテキストに動的に置き換えたり、その逆を行ったりしても、テキストを一番上にUILabel
配置します。
インターフェイスビルダーで
UILabel
最大の可能なテキストのサイズに設定Lines
属性インスペクターで「0」に設定あなたのコードで
sizeToFit
あなたのレーベルに電話するコードスニペット:
self.myLabel.text = @"Short Title";
[self.myLabel sizeToFit];
アダプティブUI(iOS8以降)の場合、UILabelの垂直方向の配置は、プロパティnoOfLines
= 0`を変更してStoryBoardから設定します。
制約
UILabel LefMargin、RightMargin、Top Margin Constraintsを調整します。
Content Compression Resistance Priority For Vertical
= 1000`を変更して、Vertical> Horizontalにします。
編集:
noOfLines=0
そして、次の制約は、望ましい結果を達成するのに十分です。
UILabelのサブクラスを作成します。魅力のように機能します:
// TopLeftLabel.h
#import <Foundation/Foundation.h>
@interface TopLeftLabel : UILabel
{
}
@end
// TopLeftLabel.m
#import "TopLeftLabel.h"
@implementation TopLeftLabel
- (id)initWithFrame:(CGRect)frame
{
return [super initWithFrame:frame];
}
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines
{
CGRect textRect = [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
textRect.origin.y = bounds.origin.y;
return textRect;
}
-(void)drawTextInRect:(CGRect)requestedRect
{
CGRect actualRect = [self textRectForBounds:requestedRect limitedToNumberOfLines:self.numberOfLines];
[super drawTextInRect:actualRect];
}
@end
ここで議論したように。
この目的を達成するために、util関数を作成しました。あなたは見てみることができます:
//複数行のラベルの高さを調整して、上に垂直になるようにします +(void)alignLabelWithTop:(UILabel *)label { CGSize maxSize = CGSizeMake(label.frame.size.width、999); label.adjustsFontSizeToFitWidth = NO; //実際の高さを取得します CGSize actualSize = [label.text sizeWithFont:label.font constrainedToSize:maxSize lineBreakMode:label.lineBreakMode]; CGRect rect = label.frame; rect.size.height = actualSize.height; label.frame = rect; }
。使い方?(lblHelloがInterface Builderによって作成されている場合、UILabel属性の詳細の一部をスキップします)
lblHello.text = @ "Hello World!Hello World!Hello World!Hello World!Hello World!Hello World!Hello World!Hello World!"; lblHello.numberOfLines = 5; [ユーティリティalignLabelWithTop:lblHello];
私はブログにも記事として書きました:http : //fstoke.me/blog/?p=2819
コードと紹介ページのコードを読むのに少し時間がかかりましたが、すべてがラベルのフレームサイズを変更しようとしているため、デフォルトの中央の垂直方向の配置が表示されません。
ただし、場合によっては、ラベルに非常に多くのテキスト(たとえば、高さが等しい複数の行)が含まれている場合でも、これらのすべてのスペースをラベルが占めるようにする必要があります。
ここでは、ラベルの最後まで改行を埋め込むだけで、別の方法で解決しました(実際にを継承したことに注意してください。ただしUILabel
、これは必須ではありません)。
CGSize fontSize = [self.text sizeWithFont:self.font];
finalHeight = fontSize.height * self.numberOfLines;
finalWidth = size.width; //expected width of label
CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
int newLinesToPad = (finalHeight - theStringSize.height) / fontSize.height;
for(int i = 0; i < newLinesToPad; i++)
{
self.text = [self.text stringByAppendingString:@"\n "];
}
ここで提案を取り、UILabelをラップできるビューを作成し、それをサイズ調整して行数を設定し、上揃えになるようにしました。UILabelをサブビューとして配置するだけです。
@interface TopAlignedLabelContainer : UIView
{
}
@end
@implementation TopAlignedLabelContainer
- (void)layoutSubviews
{
CGRect bounds = self.bounds;
for (UILabel *label in [self subviews])
{
if ([label isKindOfClass:[UILabel class]])
{
CGSize fontSize = [label.text sizeWithFont:label.font];
CGSize textSize = [label.text sizeWithFont:label.font
constrainedToSize:bounds.size
lineBreakMode:label.lineBreakMode];
label.numberOfLines = textSize.height / fontSize.height;
label.frame = CGRectMake(0, 0, textSize.width,
fontSize.height * label.numberOfLines);
}
}
}
@end
TTTAttributedLabelを使用できます。垂直方向の配置をサポートしています。
@property (nonatomic) TTTAttributedLabel* label;
<...>
//view's or viewController's init method
_label.verticalAlignment = TTTAttributedLabelVerticalAlignmentTop;
この質問の答えは少し古くなっているので、自動レイアウトファンのためにこれを追加します。
自動レイアウトにより、この問題はかなり簡単になります。ラベルをUIView *view
に追加すると仮定すると、次のコードでこれを実行できます。
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setText:@"Some text here"];
[label setTranslatesAutoresizingMaskIntoConstraints:NO];
[view addSubview:label];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[label]|" options:0 metrics:nil views:@{@"label": label}]];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[label]" options:0 metrics:nil views:@{@"label": label}]];
ラベルの高さは(を使用してintrinsicContentSize
)自動的に計算され、ラベルはの上部に端から端まで水平に配置されview
ます。
私は上記の方法の多くを使用しましたが、私が使用した迅速で汚いアプローチを追加したいだけです:
myLabel.text = [NSString stringWithFormat:@"%@\n\n\n\n\n\n\n\n\n",@"My label text string"];
文字列内の改行の数が原因で、テキストが使用可能な垂直方向のスペースを埋めることを確認し、UILabelを設定して、オーバーフローするテキストを切り捨てます。
時々十分で良いので十分です。
UITextView
ことはdlopen
、テキスト入力をサポートするために呼び出すことができるということです。これにより、UIスレッドに大きな遅延が発生する可能性があるため、このアプローチははるかにパフォーマンスが高くなります。
複数行、最小フォントサイズ、および親ビューの水平方向と垂直方向の両方の中央に配置できるラベルが必要でした。プログラムでラベルをビューに追加しました。
- (void) customInit {
// Setup label
self.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
self.label.numberOfLines = 0;
self.label.lineBreakMode = UILineBreakModeWordWrap;
self.label.textAlignment = UITextAlignmentCenter;
// Add the label as a subview
self.autoresizesSubviews = YES;
[self addSubview:self.label];
}
そして、ラベルのテキストを変更したいとき...
- (void) updateDisplay:(NSString *)text {
if (![text isEqualToString:self.label.text]) {
// Calculate the font size to use (save to label's font)
CGSize textConstrainedSize = CGSizeMake(self.frame.size.width, INT_MAX);
self.label.font = [UIFont systemFontOfSize:TICKER_FONT_SIZE];
CGSize textSize = [text sizeWithFont:self.label.font constrainedToSize:textConstrainedSize];
while (textSize.height > self.frame.size.height && self.label.font.pointSize > TICKER_MINIMUM_FONT_SIZE) {
self.label.font = [UIFont systemFontOfSize:self.label.font.pointSize-1];
textSize = [ticker.blurb sizeWithFont:self.label.font constrainedToSize:textConstrainedSize];
}
// In cases where the frame is still too large (when we're exceeding minimum font size),
// use the views size
if (textSize.height > self.frame.size.height) {
textSize = [text sizeWithFont:self.label.font constrainedToSize:self.frame.size];
}
// Draw
self.label.frame = CGRectMake(0, self.frame.size.height/2 - textSize.height/2, self.frame.size.width, textSize.height);
self.label.text = text;
}
[self setNeedsDisplay];
}
それが誰かを助けることを願っています!
FXLabel(github上)は、に設定label.contentMode
することにより、デフォルトでこれを実行しますUIViewContentModeTop
。このコンポーネントは私が作成したものではありませんが、私が頻繁に使用するコンポーネントであり、多くの機能を備えており、うまく機能しているようです。
ラベル内のテキストが垂直方向の中央に配置されていないため、これを読んでいる人にとっては、一部のフォントタイプは同じように設計されていないことに注意してください。たとえば、zapfinoサイズ16のラベルを作成する場合、テキストが垂直方向に完全に中央揃えされていないことがわかります。
ただし、helveticaを使用すると、テキストが垂直方向に中央揃えになります。
を使用しtextRect(forBounds:limitedToNumberOfLines:)
ます。
class TopAlignedLabel: UILabel {
override func drawText(in rect: CGRect) {
let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)
super.drawText(in: textRect)
}
}
UILabelをサブクラス化し、次のように描画長方形を制約します。
- (void)drawTextInRect:(CGRect)rect
{
CGSize sizeThatFits = [self sizeThatFits:rect.size];
rect.size.height = MIN(rect.size.height, sizeThatFits.height);
[super drawTextInRect:rect];
}
改行のパディングを含む解決策を試しましたが、場合によっては正しくない動作に遭遇しました。私の経験では、上記のように描画rectを制約する方が、で混乱させるよりも簡単numberOfLines
です。
PS次のようにして、UIViewContentModeを簡単にサポートすることを想像できます。
- (void)drawTextInRect:(CGRect)rect
{
CGSize sizeThatFits = [self sizeThatFits:rect.size];
if (self.contentMode == UIViewContentModeTop) {
rect.size.height = MIN(rect.size.height, sizeThatFits.height);
}
else if (self.contentMode == UIViewContentModeBottom) {
rect.origin.y = MAX(0, rect.size.height - sizeThatFits.height);
rect.size.height = MIN(rect.size.height, sizeThatFits.height);
}
[super drawTextInRect:rect];
}
複雑なタスクを実行していない限り、のUITextView
代わりにを使用できますUILabels
。
スクロールを無効にします。
テキストを完全に表示する場合はsizeToFit
、ユーザーとsizeThatFits:
メソッドのみ
迅速に、
let myLabel : UILabel!
ラベルのテキストを画面に合わせて上部に表示するには
myLabel.sizeToFit()
ラベルのフォントを画面の幅または特定の幅のサイズに合わせるため。
myLabel.adjustsFontSizeToFitWidth = YES
およびlabelのtextAlignment:
myLabel.textAlignment = .center
myLabel.textAlignment = .left
myLabel.textAlignment = .right
myLabel.textAlignment = .Natural
myLabel.textAlignment = .Justified
[myLabel sizeToFit]
。ありがとうございました!
これは古いソリューションです。iOSで自動レイアウトを使用します> = 6
私の解決策:
@interface UITopAlignedLabel : UILabel
@end
@implementation UITopAlignedLabel
#pragma mark Instance methods
- (NSArray*)splitTextToLines:(NSUInteger)maxLines {
float width = self.frame.size.width;
NSArray* words = [self.text componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSMutableArray* lines = [NSMutableArray array];
NSMutableString* buffer = [NSMutableString string];
NSMutableString* currentLine = [NSMutableString string];
for (NSString* word in words) {
if ([buffer length] > 0) {
[buffer appendString:@" "];
}
[buffer appendString:word];
if (maxLines > 0 && [lines count] == maxLines - 1) {
[currentLine setString:buffer];
continue;
}
float bufferWidth = [buffer sizeWithFont:self.font].width;
if (bufferWidth < width) {
[currentLine setString:buffer];
}
else {
[lines addObject:[NSString stringWithString:currentLine]];
[buffer setString:word];
[currentLine setString:buffer];
}
}
if ([currentLine length] > 0) {
[lines addObject:[NSString stringWithString:currentLine]];
}
return lines;
}
- (void)drawRect:(CGRect)rect {
if ([self.text length] == 0) {
return;
}
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, self.textColor.CGColor);
CGContextSetShadowWithColor(context, self.shadowOffset, 0.0f, self.shadowColor.CGColor);
NSArray* lines = [self splitTextToLines:self.numberOfLines];
NSUInteger numLines = [lines count];
CGSize size = self.frame.size;
CGPoint origin = CGPointMake(0.0f, 0.0f);
for (NSUInteger i = 0; i < numLines; i++) {
NSString* line = [lines objectAtIndex:i];
if (i == numLines - 1) {
[line drawAtPoint:origin forWidth:size.width withFont:self.font lineBreakMode:UILineBreakModeTailTruncation];
}
else {
[line drawAtPoint:origin forWidth:size.width withFont:self.font lineBreakMode:UILineBreakModeClip];
}
origin.y += self.font.lineHeight;
if (origin.y >= size.height) {
return;
}
}
}
@end