【问题标题】:Swift - UIButton with two lines of textSwift - 带有两行文本的 UIButton
【发布时间】:2015-08-21 03:53:15
【问题描述】:

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

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

谢谢

【问题讨论】:

    标签: ios swift uibutton


    【解决方案1】:

    Xcode 13 (iOS 15) 的新功能

    从 Xcode 13 开始,按钮的标题和副标题的属性可能会分开设置。

    使用情节提要:

    在按钮的属性检查器中,按标题选择“属性”。然后更改标题和副标题的字体大小。

    或以编程方式:

    // Create Title
    let titleSettings = AttributeContainer.font( UIFont(name: "HelveticaNeue-Italic", size: 17)! )
    yourButton.configuration?.attributedTitle = AttributedString("Button's Title", attributes: titleSettings)
    
    // Create Subtitle
    let subtitleSettings = AttributeContainer.font( UIFont(name: "HelveticaNeue-Italic", size: 11)! )
    yourButton.configuration?.attributedSubtitle = AttributedString("Button's Subtitle", attributes: subtitleSettings)
    

    【讨论】:

      【解决方案2】:

      不幸的是,当我想在 CollectionView 中使用多行按钮时,建议的解决方案对我来说并不奏效。然后一位同事向我展示了一个解决方法,我想分享它以防有人遇到同样的问题 - 希望这会有所帮助!创建一个继承自 UIControl 的类并使用标签对其进行扩展,然后其行为类似于按钮。

      class MultilineButton: UIControl {
      
          let label: UILabel = {
              $0.translatesAutoresizingMaskIntoConstraints = false
              $0.numberOfLines = 0
              $0.textAlignment = .center
              return $0
          }(UILabel())
      
          override init(frame: CGRect) {
              super.init(frame: frame)
      
              addSubview(label)
      
              NSLayoutConstraint.activate([
                  label.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
                  label.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
                  label.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
                  label.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
              ])
          }
      
          override var isHighlighted: Bool {
              didSet {
                  backgroundColor = backgroundColor?.withAlphaComponent(isHighlighted ? 0.7 : 1.0)
                  label.textColor = label.textColor.withAlphaComponent(isHighlighted ? 0.7 : 1.0)
              }
          }
      
          required init?(coder: NSCoder) {
              fatalError("init(coder:) has not been implemented")
          }
      }
      

      【讨论】:

        【解决方案3】:

        我的方式:

        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)
            }
        

        【讨论】:

          【解决方案4】:

          有两个问题。

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

          这可以通过使用情节提要或以编程方式实现。

          故事板:

          将“换行模式”更改为 Character WrapWord Wrap 并使用 Alt/Option + Enter 键输入新行在 UIButton 的 Title 字段中。

          以编程方式:

          override func viewDidAppear(animated: Bool) {
                  super.viewDidAppear(animated)
          
                  btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;
          }
          

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

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

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

          斯威夫特 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: [])
          }
          

          旧斯威夫特

          @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)
          
              }
          

          输出

          【讨论】:

          • 效果很好。我现在想知道是否有任何方法可以使每一行的文本居中,以及是否有任何方法可以在两行之间插入更多空间。
          • 您可以将两行文本对齐到中心。编写以下代码 btnTwoLine?.titleLabel?.textAlignment = NSTextAlignment.Center 或使用情节提要文件(控制部分->对齐)
          • 我可以知道在两者之间放置更多行的目的是什么吗?
          • 这取决于按钮的大小。如果按钮很大,那么两行文本将在中间,顶部和底部有很多空间。这不是我想要的外观。
          • 你必须在这里应用一些技巧 :) 你可以在使用多个 \n 之间放置更多行。我的意思是,“hello\n\n\nthere”会给你三个空格。但是,不要忘记修改您的代码 var newlineRange: NSRange = buttonText.rangeOfString("\n\n\n")
          【解决方案5】:

          我已经解决了这个问题,我的解决方案只在情节提要中。

          变化:

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

          • numberOfLines = 2
          • titleLabel.textAlignment = 1

          User Defined Runtime Attributes

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

          • 换行 = 自动换行

          Word wrap

          【讨论】:

            【解决方案6】:

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

                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)
            

            【讨论】:

              【解决方案7】:

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

              使所有线条居中。 只需将标题从 Plain 更改为 Attributed ,然后您就可以使每一行居中

              【讨论】:

                【解决方案8】:

                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)
                

                【讨论】:

                • 不知道为什么,但我必须添加 button.titleLabel?.numberOfLines = 0
                • 首先在 swift 4 中没有工作。需要将“换行”设置为“自动换行”。谢谢人:)
                • 之前的原始答案如下:stackoverflow.com/a/30679547/5318223
                【解决方案9】:

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

                【讨论】:

                  【解决方案10】:

                  我猜一种方法是使用标签。我这样做了,它似乎工作正常。我想我可以将它创建为 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)
                  

                  【讨论】:

                    【解决方案11】:

                    您需要在代码中执行其中的一些操作。您不能在 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)
                    
                        }
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2017-11-09
                      • 1970-01-01
                      • 2011-12-11
                      • 1970-01-01
                      • 2019-07-11
                      • 1970-01-01
                      • 2015-11-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多