代码之家  ›  专栏  ›  技术社区  ›  Owain Hunt

如何向UIButton添加多行文本?

  •  340
  • Owain Hunt  · 技术社区  · 17 年前

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

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

    24 回复  |  直到 9 年前
        1
  •  697
  •   Fattie    8 年前

    对于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. 在“换行”弹出窗口中选择 “自动换行”
        2
  •  152
  •   Adam Waite    11 年前

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

    pic

        3
  •  60
  •   Jamal Tom_B    10 年前

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

    [ here ]

        4
  •  54
  •   NiKKi    13 年前

    对于IOS 6:

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

    UILineBreakModeWordWrap and UITextAlignmentCenter
    

    在IOS 6以后的版本中不推荐使用。。

        5
  •  32
  •   ma11hew28    11 年前

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

    button.titleLabel?.numberOfLines = 0
    
        6
  •  21
  •   Community Mohan Dere    6 年前

    button.titleLabel?.lineBreakMode = .byWordWrapping
    button.titleLabel?.textAlignment = .center  
    button.setTitle("Button\nTitle",for: .normal)
    
        7
  •  15
  •   Nazrul Islam    8 年前

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

    enter image description here

    您需要将按钮标题文本对齐设置为居中

    button.titleLabel?.textAlignment = .center

    您不需要像下面这样用新行(\n)设置标题文本,

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

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

    这是结果,

    enter image description here

        8
  •  14
  •   Amir Khorsandi    7 年前

    我遇到自动布局问题,启用多行后,结果如下:
    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)
                ])
        }
    
    }
    
        9
  •  11
  •   Wienke    13 年前

    有一种更简单的方法:

    someButton.lineBreakMode = UILineBreakModeWordWrap;
    

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

    someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
    
        10
  •  11
  •   neoneye    13 年前

    在iOS7上使用自动布局左对齐:

    button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
    button.titleLabel.textAlignment = NSTextAlignmentLeft;
    button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
    
        11
  •  7
  •   Rog    17 年前

    首先,您应该知道UIButton中已经有一个UILabel。您可以使用 –setTitle:forState:

    您的示例的问题是需要设置UILabel的 numberOfLines lineBreakMode 所有物

        12
  •  5
  •   Manikandan    6 年前

      let button = UIButton()
      button.titleLabel?.lineBreakMode = .byWordWrapping
      button.titleLabel?.textAlignment = .center
      button.titleLabel?.numberOfLines = 0 // for Multi line text
    
        13
  •  4
  •   Jack    14 年前

    对于那些正在使用Xcode 4的故事板的用户,您可以单击该按钮,然后在属性检查器下的右侧实用程序窗格中,您将看到一个换行选项。选择Word Wrap,您就可以开始了。

        14
  •  4
  •   user2338871    13 年前

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

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

        15
  •  4
  •   Varrry    11 年前

    若按钮有动态标题,有一个技巧:用相同的字体放置隐藏的UILabel,并用布局将其高度与按钮高度绑定;当将文本设置为按钮、标签和自动布局时,将完成所有工作。

    笔记

    单行按钮的固有尺寸高度大于标签的高度,所以为了防止标签高度收缩,其垂直内容拥抱优先级必须大于按钮的垂直内容压缩阻力。

        16
  •  4
  •   JimHawkins    8 年前

    您必须添加以下代码:

    buttonLabel.titleLabel.numberOfLines = 0;
    
        17
  •  3
  •   jpedroso    17 年前

    另一方面,使用UILabel作为UIButton的子视图,我非常熟悉触摸事件将始终传播到UILabel的superview。

    我确实采取了这种方法,没有注意到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

        18
  •  3
  •   vially    13 年前

    preferredMaxLayoutWidth 财产:

    button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
    button.titleLabel.textAlignment = NSTextAlignmentCenter;
    button.titleLabel.preferredMaxLayoutWidth = button.frame.size.width;
    
        19
  •  3
  •   Ash    7 年前

    现在,如果您确实需要在interface builder中逐个访问此类内容,您可以通过以下简单的扩展来实现:

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

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

        20
  •  3
  •   Naresh    7 年前

    Swift 5.0 Xcode 10.2

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

    视图控制器 像这样打电话

    button.btnMultipleLines()//This is your button
    
        21
  •  3
  •   Bill Chan    6 年前

    之前 片名:

        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.我测试了标题标签?的设置。文本对齐是不必要的,标题在 .natural .

        22
  •  2
  •   makiko_fly    15 年前

    它工作得很好。

    添加要与Plist这样的配置文件一起使用,您需要使用CDATA写入多行标题,如下所示:

    <string><![CDATA[Line1
    Line2]]></string>
    
        23
  •  2
  •   Sourabh Sharma    9 年前

    button.titleLabel?.adjustsFontSizeToFitWidth = true
    button.titleLabel?.numberOfLines = 2
    
        24
  •  2
  •   ingconti    8 年前

    swift 4.0

    btn.titleLabel?.lineBreakMode = .byWordWrapping
    btn.titleLabel?.textAlignment = .center
    btn.setTitle( "Line1\nLine2", for: .normal)
    
        25
  •  1
  •   unwesen unwesen    17 年前

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

        26
  •  0
  •   Bugs Manjeet    9 年前
    self.btnError.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping
    
    self.btnError.titleLabel?.textAlignment = .center
    
    self.btnError.setTitle("Title", for: .normal)
    
        27
  •  0
  •   Stunner    8 年前

    我公司 jessecurry's answer STAButton 这是我生命的一部分 STAControls 开源库。我目前正在开发的一个应用程序中使用它,它满足了我的需要。请随时打开有关如何改进它的问题或向我发送请求。

        29
  •  0
  •   pkamb santoshIOS    5 年前

    在2021年的iOS 15中,苹果首次通过 UIButton.Configuration 应用程序编程接口。

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

    UIButton.Configuration

    What's new in UIKit 以及本届会议:

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

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

        30
  •  -4
  •   Becca Royal-Gordon    17 年前

    虽然可以向控件添加子视图,但不能保证它实际工作,因为控件可能不希望它在那里,因此可能会表现不佳。如果你能摆脱它,只需添加标签作为按钮的同级视图,并设置其框架,使其与按钮重叠;只要设置为显示在按钮顶部,按钮所能做的任何事情都不会使其模糊。

    换言之:

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