ios Swift - 带有两行文本的 UIButton

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30679370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 06:14:23  来源:igfitidea点击:

Swift - UIButton with two lines of text

iosswiftuibutton

提问by Scott

I was wondering if it is possible to create a UIButton with two lines of text. I need each line to have a different font size. The first line will be 17 point and the second will be 11 point. I've tried messing with putting two labels inside of a UIButton, but I can't get them to stay inside the bounds of the button.

我想知道是否可以用两行文本创建一个 UIButton。我需要每一行都有不同的字体大小。第一条线是 17 点,第二条线是 11 点。我试过在 UIButton 内放置两个标签,但我无法让它们留在按钮的边界内。

I'm attempting to do all of this in the ui builder, and not programmatically.

我试图在 ui builder 中完成所有这些,而不是以编程方式。

Thanks

谢谢

回答by Shamsudheen TK

There are two questions.

有两个问题。

I was wondering if it is possible to create a UIButton with two lines of text

我想知道是否可以用两行文本创建一个 UIButton

This is possible through using the storyboard or programmatically.

这可以通过使用故事板或以编程方式实现。

Storyboard:

故事板:

Change the 'Line Break Mode' to Character Wrapor Word Wrapand use Alt/Option + Enterkey to enter a new line in the UIButton's Title field.

将“行模式”更改为字符换行或自动换行,并使用Alt/Option + Enter键在 UIButton 的标题字段中输入新行。

enter image description here

在此处输入图片说明

Programmatically:

以编程方式:

override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;
}

I need each line to have a different font size 1

我需要每一行都有不同的字体大小 1

The worst case is, you can use a custom UIButtonclass and add two labels within it.

最坏的情况是,您可以使用自定义UIButton类并在其中添加两个标签。

The better way is, make use of NSMutableAttributedString. Note that,this can be achieved through only programmatically.

更好的方法是,利用NSMutableAttributedString. 请注意,这只能通过编程来实现。

Swift 5:

斯威夫特 5:

@IBOutlet weak var btnTwoLine: UIButton?

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    //applying the line break mode
    textResponseButton?.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping;
    let buttonText: NSString = "hello\nthere"

    //getting the range to separate the button title strings
    let newlineRange: NSRange = buttonText.range(of: "\n")

    //getting both substrings
    var substring1 = ""
    var substring2 = ""

    if(newlineRange.location != NSNotFound) {
        substring1 = buttonText.substring(to: newlineRange.location)
        substring2 = buttonText.substring(from: newlineRange.location)
    }

    //assigning diffrent fonts to both substrings
    let font1: UIFont = UIFont(name: "Arial", size: 17.0)!
    let attributes1 = [NSMutableAttributedString.Key.font: font1]
    let attrString1 = NSMutableAttributedString(string: substring1, attributes: attributes1)

    let font2: UIFont = UIFont(name: "Arial", size: 11.0)!
    let attributes2 = [NSMutableAttributedString.Key.font: font2]
    let attrString2 = NSMutableAttributedString(string: substring2, attributes: attributes2)

    //appending both attributed strings
    attrString1.append(attrString2)

    //assigning the resultant attributed strings to the button
    textResponseButton?.setAttributedTitle(attrString1, for: [])
}

Older Swift

年长的斯威夫特

@IBOutlet weak var btnTwoLine: UIButton?

override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        //applying the line break mode
        btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;

        var buttonText: NSString = "hello\nthere"

        //getting the range to separate the button title strings
        var newlineRange: NSRange = buttonText.rangeOfString("\n")

        //getting both substrings
        var substring1: NSString = ""
        var substring2: NSString = ""

        if(newlineRange.location != NSNotFound) {
            substring1 = buttonText.substringToIndex(newlineRange.location)
            substring2 = buttonText.substringFromIndex(newlineRange.location)
        }

        //assigning diffrent fonts to both substrings
        let font:UIFont? = UIFont(name: "Arial", size: 17.0)
        let attrString = NSMutableAttributedString(
            string: substring1 as String,
            attributes: NSDictionary(
                object: font!,
                forKey: NSFontAttributeName) as [NSObject : AnyObject])

        let font1:UIFont? = UIFont(name: "Arial", size: 11.0)
        let attrString1 = NSMutableAttributedString(
            string: substring2 as String,
            attributes: NSDictionary(
                object: font1!,
                forKey: NSFontAttributeName) as [NSObject : AnyObject])

        //appending both attributed strings
        attrString.appendAttributedString(attrString1)

        //assigning the resultant attributed strings to the button
        btnTwoLine?.setAttributedTitle(attrString, forState: UIControlState.Normal)

    }

Output

输出

enter image description here

在此处输入图片说明

回答by Nico S.

I was looking for nearly the same topic, except that I don't need two different font sizes. In case someone is looking for a simple solution:

我一直在寻找几乎相同的主题,只是我不需要两种不同的字体大小。如果有人正在寻找一个简单的解决方案:

    let button = UIButton()
    button.titleLabel?.numberOfLines = 0
    button.titleLabel?.lineBreakMode = .byWordWrapping
    button.setTitle("Foo\nBar", for: .normal)
    button.titleLabel?.textAlignment = .center
    button.sizeToFit()
    button.addTarget(self, action: #selector(rightBarButtonTapped), for: .allEvents)
    navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)

回答by Musa almatri

I have notice an issue in most of the solutions which is while making line break mode to "Character Wrap" the second line will be left aligned to the first line

我注意到大多数解决方案中存在一个问题,即在将换行模式设置为“字符换行”时,第二行将与第一行左对齐

To make all the lines centered. just change the title From Plain to Attributed and then you can make each line centered

使所有线条居中。只需将标题从普通更改为属性,然后您就可以使每行居中

attributed centered title

属性居中标题

回答by A. Trejo

I have fixed this and my solution it was only in the Storyboard.

我已经解决了这个问题,我的解决方案只在故事板中。

Changes:

变化:

It added in Identity Inspector -> User Defined Runtime Attributes(these KeyPaths):

它在Identity Inspector -> User Defined Runtime Attributes(这些 KeyPaths)中添加:

  • numberOfLines = 2
  • titleLabel.textAlignment = 1
  • 行数 = 2
  • titleLabel.textAlignment = 1

User Defined Runtime Attributes

用户定义的运行时属性

I added this in attributes inspector:

我在属性检查器中添加了这个:

  • line break = word wrap
  • 换行 = 自动换行

Word wrap

自动换行

回答by Sabhay Sardana

change line break to character wrap , select your button and in attribute inspector go to line break and change it to character wrap

将换行符更改为换行符,选择您的按钮,然后在属性检查器中转到换行符并将其更改为换行符

enter image description here

在此处输入图片说明

回答by Maksim Kniazev

SWIFT 3 Syntax

SWIFT 3 语法

let str = NSMutableAttributedString(string: "First line\nSecond Line")
str.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 17), range: NSMakeRange(0, 10))
str.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 12), range: NSMakeRange(11, 11))
button.setAttributedTitle(str, for: .normal)

回答by rdelmar

You need to do some of this in code. you can't set 2 different fonts in IB. In addition to changing the line break mode to character wrap, you need something like this to set the title,

您需要在代码中执行其中的一些操作。你不能在 IB 中设置 2 种不同的字体。除了将换行模式更改为字符换行之外,您还需要像这样设置标题,

override func viewDidLoad() {
        super.viewDidLoad()
        var str = NSMutableAttributedString(string: "First line\nSecond Line")
        str.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(17), range: NSMakeRange(0, 10))
        str.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(12), range: NSMakeRange(11, 11))
        button.setAttributedTitle(str, forState: .Normal)

    }

回答by Scott

One way to do it is with labels, I guess. I did this, and it seems to work ok. I could create this as a UIButton and then expose the labels, I guess. I don't know if this makes any sense.

我想,一种方法是使用标签。我这样做了,它似乎工作正常。我想我可以将其创建为 UIButton,然后公开标签。我不知道这是否有意义。

    let firstLabel = UILabel()

    firstLabel.backgroundColor = UIColor.lightGrayColor()
    firstLabel.text = "Hi"
    firstLabel.textColor = UIColor.blueColor()
    firstLabel.textAlignment = NSTextAlignment.Center
    firstLabel.frame = CGRectMake(0, testButton.frame.height * 0.25, testButton.frame.width, testButton.frame.height * 0.2)
    testButton.addSubview(firstLabel)

    let secondLabel = UILabel()

    secondLabel.backgroundColor = UIColor.lightGrayColor()
    secondLabel.textColor = UIColor.blueColor()
    secondLabel.font = UIFont(name: "Arial", size: 12)
    secondLabel.text = "There"
    secondLabel.textAlignment = NSTextAlignment.Center
    secondLabel.frame = CGRectMake(0, testButton.frame.height * 0.5, testButton.frame.width, testButton.frame.height * 0.2)
    testButton.addSubview(secondLabel)

回答by nastassia

my way:

我的方式:

func setButtonTitle(title: String, subtitle: String, button: UIButton){
        //applying the line break mode
        button.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping;
        let title = NSMutableAttributedString(string: title, attributes: Attributes.biggestLabel)
        let subtitle = NSMutableAttributedString(string: subtitle, attributes: Attributes.label)
        let char = NSMutableAttributedString(string: "\n", attributes: Attributes.biggestLabel)
        title.append(char)
        title.append(subtitle)
        button.setAttributedTitle(title, for: .normal)
    }