Ios UILabel word wrap功能即使有足够的空间可供单词使用,也会留下空间

Ios UILabel word wrap功能即使有足够的空间可供单词使用,也会留下空间,ios,swift,autolayout,uikit,ios-autolayout,Ios,Swift,Autolayout,Uikit,Ios Autolayout,这个问题甚至出现在故事板中 UILabel具有以下属性: numberOfLines=0 lineBreakMode=.byWordWrapping 约束:指向superview的前导和尾随26个点;垂直居中 自定义字体:中等17分 如您所见,第四个单词不能放在第一行中,因此产生了错误布局的问题。如果我去掉最后一个单词,这个句子就完全排成一行,或者说第四个单词。如果在后面添加一个单词,则会将两个单词移动到下一行,这会留下很大的空间。它应该尽量在一行中不打断或连字符地匹配单词。但很明显,即使单

这个问题甚至出现在故事板中

UILabel具有以下属性:

  • numberOfLines=0
  • lineBreakMode=.byWordWrapping
  • 约束:指向superview的前导和尾随26个点;垂直居中
  • 自定义字体:中等17分
如您所见,第四个单词不能放在第一行中,因此产生了错误布局的问题。如果我去掉最后一个单词,这个句子就完全排成一行,或者说第四个单词。如果在后面添加一个单词,则会将两个单词移动到下一行,这会留下很大的空间。它应该尽量在一行中不打断或连字符地匹配单词。但很明显,即使单词合适,也会留下空白。

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


您可能想尝试一下

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

结果:

代码(@IBDesignable,因此我们可以在IB/故事板中看到它):


你可能想试试这个

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

结果:

代码(@IBDesignable,因此我们可以在IB/故事板中看到它):

此代码可用于固定宽度标签,它将克服, 也可以得到标签的高度

此代码用于计算字体大小

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])
    }
}
获取字体大小

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])
    }
}
此代码可用于固定宽度标签,它将克服, 也可以得到标签的高度

此代码用于计算字体大小

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])
    }
}
获取字体大小

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

使用
label.sizeToFit()
。这可能会有帮助,但仍然没有帮助……苹果设计的换行算法是为了避免“寡妇”——也就是说,避免一个单词作为段落的最后一行。在谷歌上快速搜索
UILabel widows
,你会发现大量的讨论,解释了为什么会发生这种情况,以及各种尝试绕过它的方法。嗨@DonMag谢谢你为我指明了正确的方向。然而,它与文字包装没有任何关系,因为它在所有的断线模式下都表现出相同的行为。如果你将它设置为<代码>字符包,它会有不同的行为,但是当然,这会在单词中间发生断裂,我确信你不希望这样。苹果在iOS 10或iOS 11前后改变了这一点(我记得)。如果它能满足您的需要,您可以使用不可滚动、不可编辑的
UITextView
来代替
UILabel
——文本视图不能避免孤寡和孤寡(一开始我应该说“孤寡”,这是有区别的)。使用
label.sizeToFit()
。这可能会有帮助,但仍然没有帮助……苹果设计的换行算法是为了避免“寡妇”——也就是说,避免一个单词作为段落的最后一行。在谷歌上快速搜索
UILabel widows
,你会发现大量的讨论,解释了为什么会发生这种情况,以及各种尝试绕过它的方法。嗨@DonMag谢谢你为我指明了正确的方向。然而,它与文字包装没有任何关系,因为它在所有的断线模式下都表现出相同的行为。如果你将它设置为<代码>字符包,它会有不同的行为,但是当然,这会在单词中间发生断裂,我确信你不希望这样。苹果在iOS 10或iOS 11前后改变了这一点(我记得)。如果它能满足您的需要,您可以使用不可滚动、不可编辑的
UITextView
来代替您的
UILabel
——文本视图不能避免寡妇和孤儿(一开始我应该说“孤儿”,这是有区别的)。非常感谢!!:)@凯拉拉卡-哎呀。。。修正。太棒了谢谢!!:)@凯拉拉卡-哎呀。。。固定的。