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" 를 선택한 다음 "character wrap"을 선택하십시오.
Fattie

비슷한 질문에 대한 업데이트 된 답변 도 참조하십시오 .
ToolmakerSteve

버튼 텍스트 본 답변 (다중 선 너비에 맞추기, 끼워 맞춤 높이) 참조 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 에서는

일반적으로 다음 두 가지를 수행하십시오.

  1. "특성 텍스트"를 선택하십시오
  2. "줄 바꿈"팝업에서 "워드 랩"을 선택하십시오.

5
이러한 할당은 iOS 6에서 더 이상 사용되지 않습니다. 업데이트 된 구문은 @NiKKi의 아래 답변을 참조하십시오.
Aaron Brager

6
사람들이 알다시피 : NSAttributedString을 사용하는 경우 작동하지 않습니다
친구

29
실제로, button.titleLabel.numberOfLines = 0; 그것은 라인을 무제한으로 만들 것입니다. 그리고 button.titleLabel.textAlignment = NSTextAlignmentLeft; 제목이 기본적으로 가운데 맞춤이므로 왼쪽 맞춤 텍스트를 원할 경우
RyJ

4
신속하게button.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping
Robert

1
신속한 솔루션에 대해 @Robert에게 감사드립니다. 다음 NSLineBreakMode과 같이 추론을 사용하고을 생략 할 수도 있습니다 button.titleLabel?.lineBreakMode = .ByWordWrapping.
mjswensen

145

선택한 답변은 정확하지만 Interface Builder에서 이러한 종류의 작업을 선호하는 경우 다음을 수행 할 수 있습니다.

그림


58
이 답변을 작성해 주신 24 세의 본인에게 감사합니다.
Adam Waite

5
그리고 인터페이스 빌더 만 설정과 숙박에, 하나는 설정해야합니다 titleLabel.textAlignmentNumber가치 1User Defined Runtime Attributed확인하기 위해 텍스트를 중심으로
AnthoPak

2
내 24 살의 자아에서 당신의 28 살의 자아에게 감사합니다!
Daniel Springer

59

제목이 여러 줄 중앙에있는 단추를 추가하려면 단추에 대한 인터페이스 빌더 설정을 설정하십시오.

[ 여기]


이를 달성하는 방법에 대한 텍스트 설명을 추가 할 수 있습니까? 이미지는 훌륭하지만 사용할 수 없게되면 답이 쓸모가 없습니다.
Rory McCrossan

1
@RoryMcCrossan 안녕하세요, 위의 이미지를 추가했습니다. 볼 수 있습니까? Xcode 7은 여전히 ​​버그가 있으므로 버튼 제목이 사라질 수 있습니다. 그러나 앱을 실행하면 원하는 결과를 얻을 수 있습니다.
user5440039

2
이것은 실제로이 스레드에서 가장 좋은 대답입니다. 즉시 작동하며 IB의 중심 텍스트를 보여줍니다. 감사!
RainCast

@ 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

신속 : button.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping button.titleLabel?.textAlignment = NSTextAlignment.Center
jcity

30

Roger Nolan의 제안을 다시 말하지만 명시 적 코드를 사용하는 것이 일반적인 해결책입니다.

button.titleLabel?.numberOfLines = 0

21

스위프트 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

2
lineBreakMode는 UIButton의 직접 속성으로 만 사용되지 않습니다. "titleLabel의 lineBreakMode 속성을 대신 사용하십시오." 이에 따라 Valerii의 답변을 편집했습니다. 여전히 좋은 옵션입니다.
Wienke

11

자동 레이아웃을 사용하여 iOS7에서 왼쪽 정렬 :

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

9

나는 결과는 같았다 멀티 라인을 활성화 한 후, 자동 레이아웃에 문제가 있었다 : 너무 크기가 버튼의 크기에 영향을주지 않습니다 내가 추가 한 기반 , 10 살이 경우 contentEdgeInsets에 ((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)
            ])
    }

}

신속한 5에서 완벽하게 작동합니다. 또한 텍스트를 버튼 중앙에 배치하는 기능을 추가했습니다. func centerTextInButton () {guard let titleLabel = titleLabel else {return} titleLabel.textAlignment = .center}
ShadeToD

감사합니다. 그것은 좋은 해결책입니다.
Echelon

lineBreakMode / textAlignment / numberOfLines가 설정된 후에 텍스트를 설정하면 제약 조건을 추가 할 필요가 없습니다. 또한 상단 및 하단 삽입물에 titleEdgeInsets를 설정하십시오.
Bill Chan

@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을 형제 뷰로 사용하려는 브렌트의 아이디어에 관해서는, 그것은 나에게 좋은 생각처럼 보이지 않습니다. 터치 이벤트가 UIButton의 뷰를 통과하지 못하기 때문에 UILabel과의 상호 작용 문제를 계속 생각합니다.

반면에 UIButton의 하위 뷰로 UILabel을 사용하면 터치 이벤트가 항상 UILabel의 슈퍼 뷰로 전파된다는 것을 알고 매우 편합니다.

나는이 접근법을 취했고 backgroundImage 로보 고 된 문제를 보지 못했습니다. UIButton 하위 클래스의 -titleRectForContentRect :에이 코드를 추가했지만 UIButton 슈퍼 뷰의 드로잉 루틴에 코드를 배치 할 수도 있습니다.이 경우 자체에 대한 모든 참조를 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 또는 코드)으로 설정하면 단추 레이블이 여러 줄로 표시되지만 단추의 프레임에는 영향을 미치지 않습니다.

버튼에 동적 제목이 있으면 한 가지 트릭이 있습니다. 숨겨진 UILabel을 동일한 글꼴로 배치하고 레이아웃의 높이와 버튼의 높이를 묶습니다. 텍스트를 버튼 및 레이블로 설정하면 자동 레이아웃이 모든 작업을 수행합니다.

노트

단선 버튼의 고유 크기 높이는 레이블보다 크므로 레이블의 높이 축소를 방지하려면 수직 내용물 포옹 우선 순위가 버튼의 수직 내용물 압축 저항보다 커야합니다.


3

에서 스위프트 5.0엑스 코드 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

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 하위 클래스의 속성으로 레이블처럼 설정할 수 있습니다. 뷰 레이어의 모서리 반경 또는 캐스트하는 그림자의 속성과 같이 일반적으로 액세스 할 수없는 다른 모든 값에 대해서도 마찬가지입니다.


2

스위프트 5, UIButton의 여러 줄 텍스트

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

0

자신의 버튼 클래스를 굴립니다. 장기적으로 최고의 솔루션입니다. UIButton 및 기타 UIKit 클래스는 사용자 정의 방법에있어 매우 제한적입니다.


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

self.btnError.titleLabel?.textAlignment = .center

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


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)

추신 : 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

1
@GrizzlyNetch 특히 버튼의 하위보기로 추가 하지 않는 것이 좋습니다. addSubview:여기에 그것을 buttonsuperview에 추가 하여 버튼의 형제로 만들므로 중심을 일치시키는 것이 정확합니다.
브렌트 로얄-고든

아, 내 실수 야! 당신 말이 맞아, 내가 "작은"사실을 놓쳤다 그것은 그것이 superview에있다 : D ... 미안 :)
JakubKnejzlik

정확히 묻는 것이 아니라면 요소 버튼에 제목이 있기 때문에이 솔루션은 질문을 구현하는 나쁜 방법입니다.
Pablo Blanco

이것은 iPhone OS 2.0에서 합리적인 조언이었습니다. 지금까지 훨씬 더 좋은 방법이 있습니다. : ^)
브렌트 로얄-고든
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.