web-dev-qa-db-ja.com

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

次のようなコードがあります。

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

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

350
Owain Hunt

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. [改行]ポップアップで、"Word Wrap"を選択します。
654
jessecurry

選択した答えは正しいですが、Interface Builderでこのようなことをしたい場合は、次のようにします。

pic

135
Adam Waite

複数行で中央揃えされたタイトルを持つボタンを追加したい場合は、そのボタンに対するInterface Builderの設定を設定してください。

[here]

54
user5440039

IOS 6の場合:

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

として

UILineBreakModeWordWrap and UITextAlignmentCenter

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

53
NiKKi

Roger Nolanの提案をもう一度言い換えると、明示的なコードでは、これが一般的な解決策です。

button.titleLabel?.numberOfLines = 0
30
baudot

スイフト3

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

IOS 7上で自動レイアウトと左寄せ:

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

もっと簡単な方法があります。

someButton.lineBreakMode = UILineBreakModeWordWrap;

(iOS 3以降用に編集:)

someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
11
Valerii Hiora

まず第一に、あなたはUIButtonがすでにその中にUILabelを持っていることを知っておくべきです。 –setTitle:forState:を使って設定できます。

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

7
Rog

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

enter image description here

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

button.titleLabel?.textAlignment = .center

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

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

単純にタイトルを設定

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

これが結果です、

enter image description here

6
Nazrul Islam

ここでの答えは、マルチラインボタンのタイトルをプログラムで達成する方法を教えてくれます。

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

HTH

4
user2338871

Xcode 4のストーリーボードを使用している人は、このボタンをクリックすると、右側の「属性」インスペクタの下の「ユーティリティ」パネルに、「改行」のオプションが表示されます。 「ワードラップ」を選ぶと、うまくいくはずです。

4
Jack

UILabelというタイトルを兄弟関係のビューにするというBrentの考えに関しては、私にとってはあまり良い考えではありません。私はタッチイベントが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
jpedroso

このコードを追加する必要があります。

buttonLabel.titleLabel.numberOfLines = 0;
3
Pablo Blanco

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

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

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

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

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

2
Varrry

自動レイアウトを使用している場合.

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

それは完璧に機能します。

Plistのような設定ファイルでこれを使うには、CDATAを使って複数行のタイトルを書く必要があります。

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

自動レイアウトで問題が発生しました。複数行を有効にした後、結果は次のようになりました。
enter image description here
titleLabelのサイズはボタンのサイズに影響しません
Constraintsに基づいてcontentEdgeInsetsを追加しました(この場合、contentEdgeInsetsは(10、10、10、10)でした。
makeMultiLineSupport()を呼び出した後:
enter image description here
それがあなたのお役に立てばと思っています(Swift 5.0):

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)
            ])
    }

}
1
Amir Khorsandi

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

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

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

1
Ash
self.btnError.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping

self.btnError.titleLabel?.textAlignment = .center

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

Swift 5.およびXcode 10.2

SharedClass例1回書いてすべてのウェアを使う

これはあなたの共有クラスです(このようにあなたは全てのコンポーネントのプロパティを使います)

import UIKit

class SharedClass: NSObject {

     static let sharedInstance = SharedClass()

     private override init() {

     }
  }

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

あなたのViewControllerでこのように呼び出します

button.btnMultipleLines()//This is your button
0
iOS

あなた自身のボタンクラスを転がしてください。これは、長期的にははるかに優れたソリューションです。 UIButtonや他のUIKitクラスは、カスタマイズ方法が非常に制限されています。

0
unwesen

スイフト4.0

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

jessecurry's answerSTAButton を組み込みました---これは私の STAControls オープンソースライブラリの一部です。私は現在、私が開発しているアプリの1つの中でそれを使用しています、そしてそれは私の必要性のために働きます。改善方法やプルリクエストを送ってください。

0
Stunner