UIButtonに複数行のテキストをどのように追加しますか?


368

次のコードがあります...

UILabel *buttonLabel = [[UILabel alloc] initWithFrame:targetButton.bounds];
buttonLabel.text = @"Long text string";
[targetButton addSubview:buttonLabel];
[targetButton bringSubviewToFront:buttonLabel];

...ボタンに複数行のテキストを設定できるという考えですが、テキストは常にUIButtonのbackgroundImageによって隠されています。ボタンのサブビューを表示するためのロギング呼び出しは、UILabelが追加されたことを示していますが、テキスト自体は表示できません。これはUIButtonのバグですか、それとも何か問題がありますか?


7
button.titleLabel?.numberOfLines = 0
ma11hew28

2
この非常に古いQAに注意してください。最新のXcode では、「ATTRIBUTED TEXT」を非常に簡単に選択し、それから簡単です。「文字の折り返し」を選択します。
Fattie、

同様の質問に対する更新された回答もご覧ください。
ToolmakerSteve 2017年

ボタンのテキストのために(マルチライン、フィット幅、高さフィット)この回答を参照してくださいstackoverflow.com/a/59211399/7523163
ハミド・レザ・アンサリ

回答:


676

iOS 6以降の場合、次を使用して複数行を許可します。

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
// you probably want to center it
button.titleLabel.textAlignment = NSTextAlignmentCenter; // if you want to 
[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];

iOS 5以下の場合、次を使用して複数行を許可します。

button.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
// you probably want to center it
button.titleLabel.textAlignment = UITextAlignmentCenter;
[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];

2017、iOS9以降の場合、

一般に、次の2つのことを行います。

  1. 「属性テキスト」を選択
  2. 「改行」ポップアップで「ワードラップ」を選択します

5
これらの割り当てはiOS 6では廃止されていることに注意してください。更新された構文については、@ NiKKiによる以下の回答を参照してください。
アーロンブラジャー2013年

6
人だけ知っているので:あなたはNSAttributedStringを使用している場合、これは動作しません

29
実際には、button.titleLabel.numberOfLines = 0を追加するだけです。それはラインを無制限にします。そして、button.titleLabel.textAlignment = NSTextAlignmentLeft; タイトルがデフォルトで中央に配置されるため、左揃えのテキストが必要な場合。
RyJ 2014

4
迅速button.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping
ロバート

1
迅速なソリューションを提供してくれた@Robertに感謝します。次のNSLineBreakModeように、推論を使用してを省略することもできますbutton.titleLabel?.lineBreakMode = .ByWordWrapping
mjswensen 2015

145

選択した答えは正しいですが、Interface Builderでこの種のことをしたい場合は、これを行うことができます:

pic


58
この回答を書いてくれた私の24歳の自己のおかげで、28歳の自己から。
アダムウェイト2018年

5
そして、Interface Builderのみの設定を維持するには、テキストを中央に配置するために値をin に設定titleLabel.textAlignmentする必要がありますNumber1User Defined Runtime Attributed
AnthoPak

2
24歳の自分から28歳の自分に感謝します。
ダニエルスプリンガー

59

タイトルの中央に複数の行があるボタンを追加する場合は、ボタンのインターフェイスビルダーの設定を設定します。

[ ここに]


これを達成する方法のテキストによる説明を追加できますか。画像は素晴らしいですが、それが利用できなくなると、あなたの答えは役に立たなくなります。
Rory McCrossan 2015年

1
@RoryMcCrossanこんにちは、上の画像を追加しました。見えますか?Xcode 7にはまだバグがあるため、ボタンのタイトルが表示されない場合があることに注意してください。ただし、アプリを実行すると、目的の結果が得られます。
user5440039

2
これは、このスレッドでの最良の答えです。すぐに機能し、IBの中央揃えのテキストを表示します。ありがとう!
RainCast 2016年

@ user5440039素晴らしい答えをありがとう。テキストによる説明を追加する必要はありません。
Fattie

54

IOS 6の場合:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentCenter;

なので

UILineBreakModeWordWrap and UITextAlignmentCenter

IOS 6以降では非推奨です。


内部NSText.hにはFoundation非推奨の追加はありません。6.0から利用できますが、非推奨ではありません。
Alex Cio、2015年

迅速に: button.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping button.titleLabel?.textAlignment = NSTextAlignment.Center
jcity

30

ロジャーノーランの提案を言い換えると、明示的なコードを使用すると、これは一般的な解決策です。

button.titleLabel?.numberOfLines = 0

21

SWIFT 3

button.titleLabel?.lineBreakMode = .byWordWrapping
button.titleLabel?.textAlignment = .center  
button.setTitle("Button\nTitle",for: .normal)

13

Xcode 9.3 では、以下のようなストーリーボードを使用してそれを行うことができます。

ここに画像の説明を入力してください

ボタンのタイトルtextAlignmentを中央に設定する必要があります

button.titleLabel?.textAlignment = .center

以下のように、タイトルテキストを改行(\ n)で設定する必要はありません。

button.setTitle("Good\nAnswer",for: .normal)

タイトルを設定するだけで、

button.setTitle("Good Answer",for: .normal)

これが結果です

ここに画像の説明を入力してください


myButton.titleLabel.textAlignment = NSTextAlignmentCenterステートメントも必要です。
tounaobun

11

より簡単な方法があります:

someButton.lineBreakMode = UILineBreakModeWordWrap;

(iOS 3以降用に編集:)

someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;

4
UIButton.lineBreakModeは3.0で廃止されたため、これは適切なオプションではなくなりました。
Christopher Pickslay 2011年

2
lineBreakModeは、UIButtonの直接のプロパティとしてのみ非推奨です。「titleLabelのlineBreakModeプロパティを代わりに使用する」よう指示されています。私はそれに応じてヴァレリーの答えを編集しました。それはまだ良いオプションです。
Wienke、2012年

11

iOS7でautolayoutを使用して左揃え:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentLeft;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;

9

自動レイアウトに問題があり、複数行を有効にした後、結果は次のようになりました。 そのため、サイズは、(この場合contentEdgeInsetsが(10、10、10、10)に基づい て追加したボタンのサイズに影響しません)) 呼び出した後: それがあなたを助けることを願っています(Swift 5.0):
ここに画像の説明を入力してください
titleLabel
ConstraintscontentEdgeInsets
makeMultiLineSupport()
ここに画像の説明を入力してください

extension UIButton {

    func makeMultiLineSupport() {
        guard let titleLabel = titleLabel else {
            return
        }
        titleLabel.numberOfLines = 0
        titleLabel.setContentHuggingPriority(.required, for: .vertical)
        titleLabel.setContentHuggingPriority(.required, for: .horizontal)
        addConstraints([
            .init(item: titleLabel,
                  attribute: .top,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .top,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.top),
            .init(item: titleLabel,
                  attribute: .bottom,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .bottom,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.bottom),
            .init(item: titleLabel,
                  attribute: .left,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .left,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.left),
            .init(item: titleLabel,
                  attribute: .right,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .right,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.right)
            ])
    }

}

Swift 5で完璧に動作します。ボタンの中央にテキストを配置する機能も追加しました。func centerTextInButton(){guard let titleLabel = titleLabel else {return} titleLabel.textAlignment =
.center

ありがとうございました。それはそのような良い解決策です。
Echelon

制約を追加する必要はないことがわかりました。lineBreakMode/ textAlignment / numberOfLinesを設定した後でテキストを設定してください。また、上部と下部のインセットにtitleEdgeInsetsを設定します。
ビルチャン

@BillChan残念ながらすべてのケースで機能するわけではありません
Amir Khorsandi

7

まず最初に、UIButtonには既にUILabelが含まれていることに注意してください。を使用して設定でき–setTitle:forState:ます。

この例の問題は、UILabelのnumberOfLinesプロパティをデフォルト値の1以外に設定する必要があることですlineBreakMode。プロパティも確認する必要があります。


titleプロパティは知っていますが、私が知る限り、複数の行を使用するように設定することは不可能なので、このアプローチです。backgroundImageを無効にすると、UILabelが表示され、bringSubviewToFrontまたはUIButton自体のいずれかにバグがあることを示しています。
Owain Hunt

4

Xcode 4のストーリーボードを使用している場合は、ボタンをクリックすると、右側の[ユーティリティ]ペインの[属性インスペクター]に改行のオプションが表示されます。ワードラップを選択すれば、問題ありません。


4

ここでの回答は、プログラムで複数行ボタンのタイトルを実現する方法を示しています。

ストーリーボードを使用している場合、[Ctrl + Enter]を押してボタンのタイトルフィールドに強制的に改行を追加できることを追加したいと思います。

HTH



3

タイトルUILabelを兄弟ビューとして配置するというBrentの考えに関しては、私にはあまり良い考えのようには思えません。UILabelのタッチイベントがUIButtonのビューを通過しないため、UILabelとの相互作用の問題を考え続けます。

一方、UIButtonのサブビューとしてUILabelを使用すると、タッチイベントが常にUILabelのスーパービューに伝達されることを知っているので、かなり快適です。

私はこのアプローチを採用しましたが、backgroundImageで報告された問題に気づきませんでした。このコードをUIButtonサブクラスの-titleRectForContentRect:に追加しましたが、コードをUIButtonスーパービューの描画ルーチンに配置することもできます。その場合、selfへのすべての参照をUIButtonの変数に置き換える必要があります。

#define TITLE_LABEL_TAG 1234

- (CGRect)titleRectForContentRect:(CGRect)rect
{   
    // define the desired title inset margins based on the whole rect and its padding
    UIEdgeInsets padding = [self titleEdgeInsets];
    CGRect titleRect = CGRectMake(rect.origin.x    + padding.left, 
                                  rect.origin.x    + padding.top, 
                                  rect.size.width  - (padding.right + padding.left), 
                                  rect.size.height - (padding.bottom + padding].top));

    // save the current title view appearance
    NSString *title = [self currentTitle];
    UIColor  *titleColor = [self currentTitleColor];
    UIColor  *titleShadowColor = [self currentTitleShadowColor];

    // we only want to add our custom label once; only 1st pass shall return nil
    UILabel  *titleLabel = (UILabel*)[self viewWithTag:TITLE_LABEL_TAG];


    if (!titleLabel) 
    {
        // no custom label found (1st pass), we will be creating & adding it as subview
        titleLabel = [[UILabel alloc] initWithFrame:titleRect];
        [titleLabel setTag:TITLE_LABEL_TAG];

        // make it multi-line
        [titleLabel setNumberOfLines:0];
        [titleLabel setLineBreakMode:UILineBreakModeWordWrap];

        // title appearance setup; be at will to modify
        [titleLabel setBackgroundColor:[UIColor clearColor]];
        [titleLabel setFont:[self font]];
        [titleLabel setShadowOffset:CGSizeMake(0, 1)];
        [titleLabel setTextAlignment:UITextAlignmentCenter];

        [self addSubview:titleLabel];
        [titleLabel release];
    }

    // finally, put our label in original title view's state
    [titleLabel setText:title];
    [titleLabel setTextColor:titleColor];
    [titleLabel setShadowColor:titleShadowColor];

    // and return empty rect so that the original title view is hidden
    return CGRectZero;
}

私は時間をかけて、これについてもう少しここに書きました。そこでは、より短い解決策も指摘しますが、それはすべてのシナリオに完全には適合せず、いくつかのプライベートビューのハッキングを伴います。また、使用できるUIButtonサブクラスをダウンロードすることもできます。


3

iOS 6で自動レイアウトを使用する場合は、preferredMaxLayoutWidthプロパティを設定する必要がある場合もあります。

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentCenter;
button.titleLabel.preferredMaxLayoutWidth = button.frame.size.width;

3

lineBreakModeをNSLineBreakByWordWrapping(IBまたはコードのいずれか)に設定すると、ボタンのラベルは複数行になりますが、ボタンのフレームには影響しません。

ボタンに動的なタイトルがある場合、トリックが1つあります。非表示のUILabelを同じフォントで配置し、その高さとボタンの高さをレイアウトで結びます。テキストをボタンに設定すると、ラベルと自動レイアウトがすべて機能します。

注意

ワンラインボタンの本質的なサイズの高さはラベルの高さよりも大きいため、ラベルの高さの縮小を防ぐには、垂直方向のコンテンツハグの優先度をボタンの垂直方向のコンテンツ圧縮抵抗よりも大きくする必要があります。


3

スウィフト5.0Xcodeの10.2

//UIButton extension
extension UIButton {
     //UIButton properties
     func btnMultipleLines() {
         titleLabel?.numberOfLines = 0
         titleLabel?.lineBreakMode = .byWordWrapping
         titleLabel?.textAlignment = .center        
     }
}

あなたの中のViewControllerこのような呼び出し

button.btnMultipleLines()//This is your button

3

Swift 5、UIButtonの複数行テキスト用

  let button = UIButton()
  button.titleLabel?.lineBreakMode = .byWordWrapping
  button.titleLabel?.textAlignment = .center
  button.titleLabel?.numberOfLines = 0 // for Multi line text

2

それは完全に動作します。

これをPlistのような設定ファイルで使用するために追加します。CDATAを使用して、次のように複数行のタイトルを書き込む必要があります。

<string><![CDATA[Line1
Line2]]></string>

2

自動レイアウトを使用する場合。

button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.numberOfLines = 2

2

迅速な4.0

btn.titleLabel?.lineBreakMode = .byWordWrapping
btn.titleLabel?.textAlignment = .center
btn.setTitle( "Line1\nLine2", for: .normal)

2

最近、インターフェイスビルダーでケースバイケースでアクセスできるようにするためにこの種のものが本当に必要な場合は、次のような単純な拡張機能を使用して実行できます。

extension UIButton {
    @IBInspectable var numberOfLines: Int {
        get { return titleLabel?.numberOfLines ?? 1 }
        set { titleLabel?.numberOfLines = newValue }
    }
}

次に、numberOfLinesを任意のUIButtonまたはUIButtonサブクラスの属性として、まるでラベルであるかのように設定できます。同じことは、ビューのレイヤーのコーナー半径や、それがキャストするシャドウの属性など、他の通常アクセスできない値のホスト全体にも当てはまります。


0

独自のボタンクラスをロールします。長期的に見て、これは断然最良のソリューションです。UIButtonおよびその他のUIKitクラスは、それらをカスタマイズする方法に非常に制限があります。


0
self.btnError.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping

self.btnError.titleLabel?.textAlignment = .center

self.btnError.setTitle("Title", for: .normal)

0

私は、組み込まれjessecurryの答えの中STAButton私の一部ですSTAControlsオープンソースのライブラリを。現在、開発中のアプリの1つで使用しており、自分のニーズに合っています。それを改善する方法に関する問題をオープンしたり、プルリクエストを送ったりしてください。


0

タイトルラベルのボタンまでの間隔を固定するには、setTitleの前に titleEdgeInsetsおよびその他のプロパティを設定します。

    let set = UIButton()
    sut.titleLabel?.lineBreakMode = .byWordWrapping
    sut.titleLabel?.numberOfLines = 0
    sut.titleEdgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 20, right: 20)
    sut.setTitle("Dummy button with long long long long long long long long title", for: .normal)

PS私がテストしたtitleLabel?.textAlignmentの設定は不要で、タイトルはに揃ってい.naturalます。


-4

コントロールにサブビューを追加しても問題ありませんが、実際に機能する保証はありません。これは、コントロールがそこにあることを期待していない可能性があり、動作が低下する可能性があるためです。それを回避できる場合は、ボタンの兄弟ビューとしてラベルを追加し、ボタンと重なるようにフレームを設定します。ボタンの上に表示されるように設定されている限り、ボタンでできることは何もありません。

言い換えると:

[button.superview addSubview:myLabel];
myLabel.center = button.center;

2
このような醜いアプローチを提案する場合は、少なくともコード例を間違えないでください:)。サブビューの場合、ラベルの中央がボタンと同じであってはなりません。myLabel.frame = button.bounds;を使用します。またはmyLabel.center = cgPointMake(button.frame.size.with * 0.5、button.frame.size.height * 0.5)
JakubKnejzlik 2014

1
@GrizzlyNetch ボタンのサブビューとして追加しないことを特にお勧めします。addSubview:ここでは、それをbuttonのスーパービューに追加して、ボタンの兄弟にしているので、それらの中心を一致させるのは正しいことです。
ブレントRoyal-Gordon

ああ、私の間違い!あなたは正しいです、私はそれがスーパービューにある「小さな」事実を見逃しました:D ...ごめんなさい:)
JakubKnejzlik 14

要素のボタンにタイトルが付いているので、質問の内容が正確ではないため、このソリューションは質問を実装するのに不適切な方法です。
パブロブランコ

これは、iPhone OS 2.0では妥当なアドバイスでした。今までにもっと良い方法があります。:^)
ブレントロイヤルゴードン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.