如何将多行文本添加到UIButton?

时间:2009-03-03 00:22:12

标签: ios cocoa-touch uibutton uikit

我有以下代码......

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

...我的想法是我可以为按钮添加多行文本,但文本总是被UIButton的backgroundImage遮挡。用于显示按钮子视图的日志记录调用显示已添加UILabel,但无法看到文本本身。这是UIButton中的错误还是我做错了什么?

29 个答案:

答案 0 :(得分:652)

对于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. 在“换行符”弹出窗口中选择“自动换行”

答案 1 :(得分:135)

所选答案是正确的,但如果您更喜欢在Interface Builder中执行此类操作,则可以执行以下操作:

pic

答案 2 :(得分:54)

如果要添加标题以多行为中心的按钮,请设置界面生成器的按钮设置:

[here]

答案 3 :(得分:53)

对于IOS 6:

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

作为

UILineBreakModeWordWrap and UITextAlignmentCenter

在IOS 6之后已弃用..

答案 4 :(得分:30)

要重申Roger Nolan的建议,但使用明确的代码,这是一般解决方案:

button.titleLabel?.numberOfLines = 0

答案 5 :(得分:11)

使用autolayout在iOS7上左对齐:

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

答案 6 :(得分:10)

有一种更简单的方法:

someButton.lineBreakMode = UILineBreakModeWordWrap;

(针对iOS 3及更高版本编辑:)

someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;

答案 7 :(得分:7)

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

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

答案 8 :(得分:5)

在Xcode 9.3中,您可以使用 storyboard ,如下所示

enter image description here

您需要将按钮标题textAlignment设置为居中

button.titleLabel?.textAlignment = .center

您无需使用新行(\ n)设置标题文字,如下所示

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

只需设置标题,

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

结果如下,

enter image description here

答案 9 :(得分:4)

对于那些使用Xcode 4故事板的人,可以单击按钮,在“属性检查器”下的“实用工具”窗格右侧,您将看到“换行”选项。选择Word Wrap,你应该很高兴。

答案 10 :(得分:4)

这里的答案告诉您如何以编程方式实现多行按钮标题。

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

HTH

答案 11 :(得分:3)

至于布伦特关于将标题UILabel作为兄弟视角的想法,我觉得这不是一个好主意。我一直在想与UILabel的交互问题,因为它的触摸事件没有通过UIButton的观点。

另一方面,使用UILabel作为UIButton的子视图,我非常容易知道触摸事件将始终传播到UILabel的超级视图。

我确实采用了这种方法,并没有注意到backgroundImage报告的任何问题。我在UIButton子类的-titleRectForContentRect:中添加了这段代码,但代码也可以放在UIButton superview的绘图例程中,在这种情况下,你应该用UIButton的变量替换对self的所有引用。

#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子类。

答案 12 :(得分:3)

您必须添加以下代码:

buttonLabel.titleLabel.numberOfLines = 0;

答案 13 :(得分:2)

效果很好。

添加使用配置文件如Plist,你需要使用CDATA来编写多线标题,如下所示:

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

答案 14 :(得分:2)

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

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

答案 15 :(得分:2)

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

如果按钮具有动态标题,则有一个技巧:将隐藏的UILabel与相同的字体放在一起,并将其高度与按钮的高度与布局相关联;当将文本设置为按钮和标签时​​,自动布局将完成所有工作。

注意

单行按钮的内在尺寸高度大于标签的高度,因此为了防止标签的高度缩小,它的垂直内容拥抱优先级必须大于按钮的垂直内容抗压缩性。

答案 16 :(得分:2)

如果您使用自动布局。

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

答案 17 :(得分:1)

要将标题标签的间距固定到按钮,请在设置之前设置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)

P.S。我测试了是否设置titleLabel?.textAlignment,并且标题在.natural中对齐。

答案 18 :(得分:1)

这几天,如果您确实需要视情况在接口构建器中访问此类内容,则可以使用以下简单扩展来做到这一点:

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

然后,您可以简单地将numberOfLines设置为任何UIButton或UIButton子类上的属性,就好像它是标签一样。整个其他通常无法访问的值也是如此,例如视图图层的角半径或它投射的阴影的属性。

答案 19 :(得分:1)

我在自动布局方面遇到问题,启用多行后结果如下:
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)
            ])
    }

}

答案 20 :(得分:0)

“添加按钮”约束和子视图。这就是我在项目中所做的事情,可以这样说。实际上,我有99%的时间是通过程序制作所有内容。.因为这对我来说要容易得多。情节提要有时可能真的很容易出错 [1]:https://i.stack.imgur.com/5ZSwl.png

答案 21 :(得分:0)

在 2021 年的 iOS 15 中,Apple 首次通过 UIButton.Configuration API 正式支持多行 UIButton。

<块引用>

UIButton.Configuration

指定按钮外观和行为及其内容的配置。

UIButton.Configuration

What's new in UIKit 和会话中探索了这个新 API:

<块引用>

认识 UIKit 按钮系统

每个应用都使用按钮。在 iOS 15 中,您可以采用更新的样式来创建可轻松融入界面的华丽按钮。我们将探索可让您更轻松地创建不同类型按钮的功能,了解如何提供更丰富的交互,并了解如何在使用 Mac Catalyst 时获得出色的按钮。

https://developer.apple.com/videos/play/wwdc2021/10064/

答案 22 :(得分:0)

快捷键5,用于UIButton中的多行文本

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

答案 23 :(得分:0)

Swift 5.0 Xcode 10.2

SharedClass 示例编写一次并使用每种商品

这是您的共享类(像这样,您将使用所有组件的属性)

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

答案 24 :(得分:0)

我在jessecurry's answer中加入了STAButton,这是STAControls开源库的一部分。我目前在我正在开发的其中一个应用程序中使用它,它可以满足我的需求。请随意打开有关如何改进或向我发送拉取请求的问题。

答案 25 :(得分:0)

swift 4.0

private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    .
    Task sumTask = SumPageSizesAsync();
    .
}


private async Task SumPageSizesAsync()
{
    HttpClient client = new HttpClient() { MaxResponseContentBufferSize = 1000000 };

    List<string> urlList = SetUpURLList();

    IEnumerable<Task<int>> downloadTasksQuery = from url in urlList select ProcessURLAsync(url);
    Task<int>[] downloadTasks = downloadTasksQuery.ToArray();

    Task<int[]> whenAllTask = Task.WhenAll(downloadTasks);

    int[] lengths = await whenAllTask;

    int total = lengths.Sum();

    // Display the total count for all of the web addresses.  
    resultsTextBox.Text += string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);

    // where's the return statement?
}

答案 26 :(得分:0)

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

self.btnError.titleLabel?.textAlignment = .center

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

答案 27 :(得分:0)

滚动你自己的按钮类。从长远来看,它是迄今为止最好的解决方案。 UIButton和其他UIKit类在如何自定义它们方面非常严格。

答案 28 :(得分:-3)

虽然可以将一个子视图添加到控件中,但不能保证它实际上可以正常工作,因为控件可能不会指望它在那里并因此可能表现不佳。如果您可以使用它,只需将标签添加为按钮的同级视图并设置其框架,使其与按钮重叠;只要它设置为显示在按钮顶部,按钮可以做的任何事都不会使它模糊不清。

换句话说:

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