UILabel 自动换行功能留下 space,即使有足够的 space 可用于单词

UILabel word wrap feature leaving space even when sufficient space available for the word

这个问题甚至出现在情节提要中。

UILabel 具有以下属性:

如您所见,第四个词无法放在第一行中,因此由于布局不当而出现问题。如果我删除最后一个词,则句子完全适合一行或说出第四个词。如果在将它们都移动到下一行后添加一个单词,则会留下很多 space。它应该尽量在一行中不打断或连字符地排列单词。但显然空 space 即使 word 可以容纳。

您可以在新项目中重新创建它并观察问题。

您可能想尝试一下...

子类 UITextView,禁用滚动、编辑和选择...将 textContainerInset = UIEdgeInsets.zerotextContainer.lineFragmentPadding = 0 设置为零。

结果:

代码(@IBDesignable 所以我们可以在 IB / Storyboard 中看到它):

@IBDesignable
class TextViewLabel: UITextView {

    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    func commonInit() -> Void {
        isScrollEnabled = false
        isEditable = false
        isSelectable = false
        textContainerInset = UIEdgeInsets.zero
        textContainer.lineFragmentPadding = 0
    }

}

This code can be used in fixed width label and it will overcome that, also can get the height of the label

  private static func calculateLabelProperties() -> (String, CGFloat){

    let titleString = "Your string here"

        let wordArray = titleString.components(separatedBy: " ")
        var lineCount = 1//first line denoted by 1
        var tempWidth:CGFloat = 0
        var title = ""
        for (index,element) in wordArray.enumerated() {
            let width = calculateFontSize(title: element + " ", fontName: "your font name", fontSize: 17).width
            tempWidth = tempWidth + width

            //get the nextelement
            var nextElement = ""
            if wordArray.count > index + 1 {
                nextElement = wordArray[index + 1]
            }

            let nextElementWidth = calculateFontSize(title: nextElement, fontName: "your font name", fontSize: 17).width

            if tempWidth + nextElementWidth > 410 {//410 is labelwidth
                tempWidth = 0
                lineCount += 1
                title = "\(title)\(element)\n"
            } else {
                title = "\(title)\(element) "
            }
        }
        return (title, CGFloat(lineCount * 20))//20 is label sigle line height
    }

此代码计算字体大小

func calculateFontSize(title: String, fontName: String, fontSize: CGFloat) -> (width: CGFloat, height: CGFloat){
    let font = UIFont(name: fontName, size: fontSize)
    return (title.size(OfFont: font!).width, title.size(OfFont: font!).height)
}

获取字体大小

extension String {
    func size(OfFont font: UIFont) -> CGSize {
        return (self as NSString).size(withAttributes: [NSAttributedString.Key.font: font])
    }
}