由于字体大小的变化,Swift标签没有更新框架

Posted

技术标签:

【中文标题】由于字体大小的变化,Swift标签没有更新框架【英文标题】:Swift label not updating frame due change of font size 【发布时间】:2020-09-16 05:43:39 【问题描述】:

目前,我正在创建一个表格视图,其中包含一个 imageView 作为单元格内的主要 UI 项,并且在顶部有一个标签的操作。现在我面临一个问题,对于长文本,标签的框架不准确,对于长文本,它占用了大量空间,似乎有换行符但没有,这是问题:

Label issue

这是标签的属性 Label properties

这是我的ViewController 和我正在使用的约束 View Controller on Storyboard

其他细节

    对于 Cell,我没有添加额外的代码,我只有 IBOutlets,仅此而已。 在CellForRowAtIndexPath 上,除了设置图像和设置文本之外,我没有做更多的代码。

谢谢

【问题讨论】:

你试过在实际设备上运行它吗? 这能回答你的问题吗? How to control the line spacing in UILabel 【参考方案1】:

尝试改变内容拥抱标签的优先级

【讨论】:

【参考方案2】:

您选择的字体 - Noto Nastaliq Urdu Bold - 具有非常特定的类型布局属性。

将其与默认系统字体进行比较。

使用此代码:

    let fontDefault = UIFont.systemFont(ofSize: 17.0, weight: .bold)
    guard let fontNotoBld = UIFont(name: "NotoNastaliqUrdu-Bold", size: 17) else 
        fatalError("Could not create font!")
    

    print("fontDefault.lineHeight:\t",fontDefault.lineHeight)
    print("fontNotoBld.lineHeight:\t",fontNotoBld.lineHeight)
    print()
    
    print("fontDefault.ascender:\t",fontDefault.ascender)
    print("fontNotoBld.ascender:\t",fontNotoBld.ascender)
    print()

    print("fontDefault.descender:\t",fontDefault.descender)
    print("fontNotoBld.descender:\t",fontNotoBld.descender)
    print()

    print("fontDefault.xHeight:\t",fontDefault.xHeight)
    print("fontNotoBld.xHeight:\t",fontNotoBld.xHeight)
    print()

    print("fontDefault.capHeight:\t",fontDefault.capHeight)
    print("fontNotoBld.capHeight:\t",fontNotoBld.capHeight)
    print()

我们在调试控制台中得到这个输出:

fontDefault.lineHeight:  20.287109375
fontNotoBld.lineHeight:  42.5

fontDefault.ascender:    16.1865234375
fontNotoBld.ascender:    32.368

fontDefault.descender:   -4.1005859375
fontNotoBld.descender:   -10.132000000000001

fontDefault.xHeight:     9.13916015625
fontNotoBld.xHeight:     9.112

fontDefault.capHeight:   11.97802734375
fontNotoBld.capHeight:   12.138000000000002

我不知道具体原因,但我的假设是 Noto Nastaliq Urdu 支持更多的语言字符,这些字符通常具有非常不同的形状和高度。

您可以使用更标准的字体,也可以设计 UI 以适应更大的间距。


编辑

您可以尝试使用带有行高设置的属性文本。但是,它会影响文本的顶部间距,可能不够用。

这是一个带有 3 个标签的示例:

顶部标签使用默认设置

第二个标签将 maximumLineHeight 更改为 17

第三个标签将 maximumLineHeight 更改为 26

  let titleText = "Label with enough text to cause word wrapping onto multiple lines."

  guard let fontNotoBold = UIFont(name: "NotoNastaliqUrdu-Bold", size: 17) else 
      fatalError("Could not create font!")
  

  // without paragraphStyle attribute
  var attrString = NSMutableAttributedString(string: titleText)
  attrString.addAttribute(NSAttributedString.Key.font, value: fontNotoBold, range:NSMakeRange(0, attrString.length))
  label1.attributedText = attrString

  // with paragraphStyle max line height: 17
  let ps2 = NSMutableParagraphStyle()
  ps2.maximumLineHeight = 17
  attrString = NSMutableAttributedString(string: titleText)
  attrString.addAttribute(NSAttributedString.Key.font, value: fontNotoBold, range:NSMakeRange(0, attrString.length))
  attrString.addAttribute(NSAttributedString.Key.paragraphStyle, value:ps2, range:NSMakeRange(0, attrString.length))
  label2.attributedText = attrString

  // with paragraphStyle max line height: 26
  let ps3 = NSMutableParagraphStyle()
  ps3.maximumLineHeight = 26
  attrString = NSMutableAttributedString(string: titleText)
  attrString.addAttribute(NSAttributedString.Key.font, value: fontNotoBold, range:NSMakeRange(0, attrString.length))
  attrString.addAttribute(NSAttributedString.Key.paragraphStyle, value:ps3, range:NSMakeRange(0, attrString.length))
  label3.attributedText = attrString

结果如下:

多做一些实验,例如在开头添加一个换行符 ("\n"),您也许可以得到令人满意的外观。

【讨论】:

以上是关于由于字体大小的变化,Swift标签没有更新框架的主要内容,如果未能解决你的问题,请参考以下文章

Swift:如何让 UILabel 从另一个 UIlabel 继承字体大小?

获取字体大小

swift实现动态字体

根据自动布局更改 UILabel 中的字体大小(swift)

设置字体需要覆盖 sizeToFit() Swift 的大小

Swift font.withSize 不会改变 UILabel 上的字体大小