2009-03-03 19 views
301

我有以下代码...如何将多行文本添加到UIButton?

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

...的想法是,我可以有按钮多行文本,但文本始终是由UIButton的中和backgroundImage模糊。显示按钮子视图的日志调用显示已添加UILabel,但文本本身无法看到。这是UIButton中的错误还是我做错了什么?

+3

`button.titleLabel .numberOfLines = 0` – ma11hew28 2015-05-12 23:46:37

+1

请注意这个非常非常老QA ,在现代的Xcode **非常简单,选择“属性文本”**,然后它是微不足道的,选择“字符包装”。 – Fattie 2016-12-07 15:05:56

+0

也见[更新的答案](http://stackoverflow.com/a/7832414/199364)到一个类似的问题。 – ToolmakerSteve 2017-03-06 00:11:31

回答

608

对于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及以下版本,使用follo翼允许多行:

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

2017年,为iOS9向前

一般,只是做这两件事情:

  1. 选择“属性文本”
  2. 在“换行符”弹出式菜单中选择“文字换行”
7

首先,你应该知道UIButton里面已经有了UILabel。您可以使用–setTitle:forState:进行设置。

您示例的问题在于您需要将UILabel的numberOfLines属性设置为默认值1以外的值。您还应该查看lineBreakMode属性。

+0

我知道标题属性,但据我可以告诉它不可能设置它使用多个行,因此这种方法。如果我禁用了backgroundImage,我的UILabel显示出来了,这对我来说暗示了bringSubviewToFront或者UIButton本身的错误。 – 2009-03-03 11:43:47

-1

尽管向控件添加子视图是可以的,但并不能保证它实际上能够正常工作,因为控件可能不会期望它在那里,因此可能表现不佳。如果您可以避开它,只需将该标签添加为该按钮的同级视图并设置其框架,使其与该按钮重叠;只要它被设置为出现在按钮的顶部,该按钮可以做的任何事都不会掩盖它。

换句话说:

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

请,如果你建议这种丑陋的方法,至少不要在你的代码示例中犯错:)。如果它是子视图,标签不应该与按钮具有相同的中心。使用myLabel.frame = button.bounds;或myLabel.center = cgPointMake(button.frame.size.with * 0.5,button.frame.size.height * 0.5) – JakubKnejzlik 2014-08-06 14:53:04

+1

@GrizzlyNetch我特意建议*不*将其添加为按钮的子视图。 `addSubview:`在这里将它添加到`button`的超级视图,因此使它成为按钮的同级,所以匹配它们的中心是正确的。 – 2014-08-08 06:49:49

+0

啊,我的错!你是对的,我错过了它在超级视图中的“小”事实:D ...对不起:) – JakubKnejzlik 2014-08-08 08:16:48

3

至于把标题的UILabel作为兄弟鉴于布伦特的想法,它似乎并不像我一个非常好的主意。我一直在思考与UILabel的交互问题,因为它的触摸事件没有通过UIButton的观点。

另一方面,用UILabel作为UIButton的子视图,我知道触摸事件总是会传播到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; 
} 

我确实花时间写了更多关于这个here。在那里,我还指出了一个较短的解决方案,虽然它不太适合所有情况,并涉及一些私人视图黑客攻击。在那里,你可以下载一个可以使用的UIButton子类。

0

滚动您自己的按钮类。从长远来看,这是迄今为止最好的解决方案。 UIButton和其他UIKit类对于如何定制它们的限制很大。

10

有一种更简单的方法:

someButton.lineBreakMode = UILineBreakModeWordWrap; 

(编辑为iOS 3和更高:)

someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap; 
+4

UIButton.lineBreakMode在3.0中被弃用,所以这不再是一个好的选择。 – 2011-01-17 23:12:21

28

要重申罗杰·诺兰的建议,但有明确的代码,这是一般的解决方案:

button.titleLabel?.numberOfLines = 0 
1

它完美。

添加到具有类似的plist配置文件中使用此,你需要使用CDATA写multilined标题,就像这样:

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

对于那些谁正在使用的Xcode 4的故事板,您可以点击按钮,并在属性检查器下的Utilities面板右侧,您会看到一个Line Break选项。选择Word Wrap,你应该很好走。

53

对于iOS 6:

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

由于

UILineBreakModeWordWrap and UITextAlignmentCenter 

在IOS 6日起已被弃用。这里

3

答案告诉你如何通过编程实现多按钮标题。

我只是想补充一点,如果你使用故事板,你可以输入[Ctrl + Enter]在按钮标题字段上强制换行。

HTH

2

如果使用自动布局在iOS 6,你可能还需要设置preferredMaxLayoutWidth属性:

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

留在iOS7对准自动布局:

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

的选择的答案是正确的,但如果你喜欢在Interface Builder中做这样的事情,你可以这样做:

pic

2

将lineBreakMode设置为NSLineBreakByWordWrapping(在IB或代码中)使按钮标签为多行,但不影响按钮的框架。

如果按钮具有动态标题,则有一个技巧:将隐藏的UILabel设置为相同的字体,并将其高度与布局的高度绑定;当设置文本按钮和标签和自动布局将使所有的工作。

注意

一行按钮的固有大小高度比标签的更大,因此要防止标签的高度缩小它的垂直内容拥抱优先级必须大于按钮的垂直内容压缩阻力。如果您使用自动布局

[here]

36

如果你想用多行居中标题中添加一个按钮,设置你的界面生成器的按钮设置。

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

14

SWIFT 3

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

你必须添加以下代码:?

buttonLabel.titleLabel.numberOfLines = 0;