【问题标题】:Multiline UIButton autosize per line多行 UIButton 每行自动调整大小
【发布时间】:2015-06-20 06:16:14
【问题描述】:

我想使用标准的UIButton,但我想放在UIButton 上的文字有......

  1. ...多行(每行是不同的字符串)和...
  2. ...每一行应该有不同的字体和大小...
  3. ... 自动调整字体大小以适应按钮宽度(而不是高度使其 简单一点)

所以,即使很难,我也想为每一行设置(首选)字体大小,我希望字体大小自动缩小,以便 每个单独的行 很好地适合 @987654324 @(=与UILabel AutoShrink / 最小字体比例相同的行为)。

我不想要的:

我不想开始将 UILabel 添加到 UIButton(例如作为子视图)或使用 IB 将 UILabel 放在场景上并在其周围绘制一个 UIButton(为什么:我想要标准的 UIButton 突出显示行为)

我想要什么:

一个使用属性字符串的干净解决方案,给定宽度会缩小字体(我猜会更新属性字符串),如果需要的话逐行。

我的想法,实现一个这样的函数:

    func addToAttributedString(attString : NSMutableAttributedString, plainString : String, font : UIFont, preferredSize : CGFloat, maxWidth : CGFloat)

然后我可以通过使用文本 1,2,3... 调用它来创建属性字符串,并在它们之间插入换行符 (\n)。

有什么想法吗?

【问题讨论】:

  • 如果您使用 UILabel 而不是 UIButton,您可以在 xib 中使用“AutoShrink”选项来设置“MinimumFontSize”。

标签: ios swift uibutton nsattributedstring


【解决方案1】:

sizeToFit()会帮你调整文字高度。

    var str : NSMutableAttributedString = NSMutableAttributedString(string: "Bla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla\nBla")
    str.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(20), range: NSRange(location: 13,length: 3))
    button.setAttributedTitle(str, forState: UIControlState.Normal)
    button.titleLabel!.lineBreakMode = .ByWordWrapping
    button.titleLabel?.textAlignment = .Center
    button.titleLabel?.adjustsFontSizeToFitWidth = true
    button.sizeToFit()
    button.layoutIfNeeded()

也使用您的代码:

    var attrString = NSMutableAttributedString()
    addNewLineToAttributedString(attrString, plainString: "Big title", font: UIFont.systemFontOfSize(10), preferredSize: 50, maxWidth: 100)
    addNewLineToAttributedString(attrString, plainString: "Smaller text", font: UIFont.systemFontOfSize(10), preferredSize: 50, maxWidth: 100)
    addNewLineToAttributedString(attrString, plainString: "Smaller smaller text", font: UIFont.systemFontOfSize(10), preferredSize: 50, maxWidth: 100)
    addNewLineToAttributedString(attrString, plainString: "Smaller Smaller Smaller text", font: UIFont.systemFontOfSize(10), preferredSize: 50, maxWidth: 100)
    addNewLineToAttributedString(attrString, plainString: "Smaller Smaller Smaller text", font: UIFont.systemFontOfSize(10), preferredSize: 50, maxWidth: 100)
    addNewLineToAttributedString(attrString, plainString: "Big title", font: UIFont.systemFontOfSize(10), preferredSize: 50, maxWidth: 100)
    addNewLineToAttributedString(attrString, plainString: "Big title", font: UIFont.systemFontOfSize(10), preferredSize: 50, maxWidth: 100)
    addNewLineToAttributedString(attrString, plainString: "Smaller Smaller Smaller text", font: UIFont.systemFontOfSize(10), preferredSize: 50, maxWidth: 100)
    addNewLineToAttributedString(attrString, plainString: "Smaller Smaller Smaller text", font: UIFont.systemFontOfSize(10), preferredSize: 50, maxWidth: 100)
    addNewLineToAttributedString(attrString, plainString: "Smaller Smaller Smaller text", font: UIFont.systemFontOfSize(10), preferredSize: 50, maxWidth: 100)
    addNewLineToAttributedString(attrString, plainString: "Smaller Smaller Smaller text", font: UIFont.systemFontOfSize(10), preferredSize: 50, maxWidth: 100)
    button.setAttributedTitle(attrString, forState: UIControlState.Normal)
    button.titleLabel!.lineBreakMode = .ByWordWrapping
    button.titleLabel?.textAlignment = .Center
    button.titleLabel?.adjustsFontSizeToFitWidth = true
    button.sizeToFit()
    button.layoutIfNeeded()

【讨论】:

  • 试过了,但没有提供所需的结果。请注意,由 \n 分隔的 4 个字符串也有不同的字体(下划线、粗体)和不同的首选大小
  • 是的,它当然可以与我的代码一起使用,因为 addNewLineToAttributedString 会根据宽度调整字符串的大小!
  • @HixField 没有你的代码也可以工作。正如我之前添加的那样。
  • @HixField 无论如何都要离开它,如果你得到了输出。谢谢
  • 感谢您的尝试,在下面查看我修改后的答案,现在使用扩展和重载运算符(更简洁的代码)。
【解决方案2】:

您可以使用 Storyboard it self 来实现它。只需执行此步骤

1:将按钮类型从 System 更改为 Custome

2:将按钮标题从 plain 更改为 attributed

3:在 textArea 中输入文本,当您需要换行时按 Alt + Enter。看图片它会把我的文字分成3行。

4:现在将换行模式设置为Character Wrap

注意:如果您在情节提要的不同行中看不到文本,请将文本对齐方式从 自然对齐改为左对齐。设置为图像中的选择部分

5:现在选择单行并设置字体。你也可以改变textColor。

6:对每一行重复Step5

这是我的模拟器输出:

【讨论】:

  • +1 for ALT - ENTER 开始新行!但是,很抱歉没有在 org 问题中指定这一点,但文本是以编程方式设置的。我想出了一个解决方案,请参阅下面的答案:)
【解决方案3】:

想出了一个解决方案(请查看我的博客 http://www.hixfield.net/blog/2015/06/multiline-uibutton-with-each-line-resized-to-fit-width/ 了解更多信息)

class ViewController: UIViewController {

    //the button that we are formatting
    @IBOutlet weak var btn: UIButton!

    //setup our button in the will appear function
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        setupBtn()
    }

    //function that does the magic
    func setupBtn() {
        btn.titleLabel?.lineBreakMode=NSLineBreakMode.ByWordWrapping
        var attrString = NSMutableAttributedString()
        var attr = [NSFontAttributeName : UIFont.systemFontOfSize(10)]
        attrString += (NSMutableAttributedString(string : "Big title", font: UIFont.systemFontOfSize(50), maxWidth: 100)! + "\n" )
        attrString += (NSMutableAttributedString(string : "Smaller text", font: UIFont.systemFontOfSize(50), maxWidth: 100)!  + "\n" )
        attrString += (NSMutableAttributedString(string : "Smaller smaller text", font: UIFont.systemFontOfSize(80), maxWidth: 100)! + "\n" )
        btn.setAttributedTitle(attrString, forState: UIControlState.Normal)
    }
}

//************************

extension NSMutableAttributedString {
    /**Makes an attributes string with the specified (plain) string and font but resizes the font smaller
    to fit the width if required. Can return nil, if there is no way to make it fit*/
    convenience init?(string : String, font : UIFont, maxWidth : CGFloat){
        self.init()
        for var size = font.pointSize ; size>1 ; size-- {
            let attrs = [NSFontAttributeName : font.fontWithSize(size)]
            let attrString = NSAttributedString(string: string, attributes: attrs)
            if attrString.size().width <= maxWidth {
                self.setAttributedString(attrString)
                return
            }
        }
        return nil
    }
}

//************************

public func += (inout left: NSMutableAttributedString, right: NSAttributedString) {
    left.appendAttributedString(right)
}

public func + (left: NSAttributedString, right: NSAttributedString) -> NSAttributedString {
    var result  = NSMutableAttributedString(attributedString: right)
    result.appendAttributedString(right)
    return result
}

public func + (left: NSAttributedString, right: String) -> NSAttributedString {
    var result  = NSMutableAttributedString(attributedString: left)
    result.appendAttributedString(NSAttributedString(string: right))
    return result
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    • 2012-11-12
    相关资源
    最近更新 更多