UILabel 自动换行功能留下 space,即使有足够的 space 可用于单词
UILabel word wrap feature leaving space even when sufficient space available for the word
这个问题甚至出现在情节提要中。
UILabel 具有以下属性:
- 行数 = 0
- lineBreakMode = .byWordWrapping
- 约束:前导和尾随 26 点到 superview;垂直居中。
- 自定义字体:中号 17 磅。
如您所见,第四个词无法放在第一行中,因此由于布局不当而出现问题。如果我删除最后一个词,则句子完全适合一行或说出第四个词。如果在将它们都移动到下一行后添加一个单词,则会留下很多 space。它应该尽量在一行中不打断或连字符地排列单词。但显然空 space 即使 word 可以容纳。
您可以在新项目中重新创建它并观察问题。
您可能想尝试一下...
子类 UITextView
,禁用滚动、编辑和选择...将 textContainerInset = UIEdgeInsets.zero
和 textContainer.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])
}
}
这个问题甚至出现在情节提要中。
UILabel 具有以下属性:
- 行数 = 0
- lineBreakMode = .byWordWrapping
- 约束:前导和尾随 26 点到 superview;垂直居中。
- 自定义字体:中号 17 磅。
如您所见,第四个词无法放在第一行中,因此由于布局不当而出现问题。如果我删除最后一个词,则句子完全适合一行或说出第四个词。如果在将它们都移动到下一行后添加一个单词,则会留下很多 space。它应该尽量在一行中不打断或连字符地排列单词。但显然空 space 即使 word 可以容纳。
您可以在新项目中重新创建它并观察问题。
您可能想尝试一下...
子类 UITextView
,禁用滚动、编辑和选择...将 textContainerInset = UIEdgeInsets.zero
和 textContainer.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])
}
}