现在,我假设-因为你有行数设置为零,标签是远远高于需要-你将有更多的文本,而不仅仅是一个单词...但是,让我们先来一个单词的“修复”。 一些搜索发现这篇文章(不是我的):Dynamic Text Resizing in Swift,它使用了几个UILabel扩展来“将文本适合标签”。下面是相关代码-唯一的修改是将旧的NSAttributedStringKey更改为NSAttributedString.Key:
extension UIFont {
/**
Will return the best font conforming to the descriptor which will fit in the provided bounds.
*/
static func bestFittingFontSize(for text: String, in bounds: CGRect, fontDescriptor: UIFontDescriptor, additionalAttributes: [NSAttributedString.Key: Any]? = nil) -> CGFloat {
let constrainingDimension = min(bounds.width, bounds.height)
let properBounds = CGRect(origin: .zero, size: bounds.size)
var attributes = additionalAttributes ?? [:]
let infiniteBounds = CGSize(width: CGFloat.infinity, height: CGFloat.infinity)
var bestFontSize: CGFloat = constrainingDimension
for fontSize in stride(from: bestFontSize, through: 0, by: -1) {
let newFont = UIFont(descriptor: fontDescriptor, size: fontSize)
attributes[.font] = newFont
let currentFrame = text.boundingRect(with: infiniteBounds, options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: attributes, context: nil)
if properBounds.contains(currentFrame) {
bestFontSize = fontSize
break
}
}
return bestFontSize
}
static func bestFittingFont(for text: String, in bounds: CGRect, fontDescriptor: UIFontDescriptor, additionalAttributes: [NSAttributedString.Key: Any]? = nil) -> UIFont {
let bestSize = bestFittingFontSize(for: text, in: bounds, fontDescriptor: fontDescriptor, additionalAttributes: additionalAttributes)
return UIFont(descriptor: fontDescriptor, size: bestSize)
}
}
extension UILabel {
/// Will auto resize the contained text to a font size which fits the frames bounds.
/// Uses the pre-set font to dynamically determine the proper sizing
func fitTextToBounds() {
guard let text = text, let currentFont = font else { return }
let bestFittingFont = UIFont.bestFittingFont(for: text, in: bounds, fontDescriptor: currentFont.fontDescriptor, additionalAttributes: basicStringAttributes)
font = bestFittingFont
}
private var basicStringAttributes: [NSAttributedString.Key: Any] {
var attribs = [NSAttributedString.Key: Any]()
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = self.textAlignment
paragraphStyle.lineBreakMode = self.lineBreakMode
attribs[.paragraphStyle] = paragraphStyle
return attribs
}
}
1条答案
按热度按时间a8jjtwal1#
尝试在多行标签上实现字体缩放和换行是一项长期存在的任务。
第一个问题与使用自动收缩没有直接关系。
从换行模式下的Apple's docs:
casebyWordWrapping
指示换行发生在单词边界处的值,除非单词不适合一行。
因此,
UILabel
与system font / bold / 60
,行数:0
,约束为w: 300.0, h: 160.0
,我们得到:如果我们将自动收缩设置为
0.5
的最小尺度,我们会得到同样的结果...因为标签足够高以缠绕在多条线上。如果我们将表的高度更改为
120.0
-所以它只够一行的高度-字体缩放将会发生,我们会得到这样的结果:现在,我假设-因为你有行数设置为零,标签是远远高于需要-你将有更多的文本,而不仅仅是一个单词...但是,让我们先来一个单词的“修复”。
一些搜索发现这篇文章(不是我的):Dynamic Text Resizing in Swift,它使用了几个
UILabel
扩展来“将文本适合标签”。下面是相关代码-唯一的修改是将旧的NSAttributedStringKey
更改为NSAttributedString.Key
:然后我们调用
label.fitTextToBounds()
(viewDidLayoutSubviews()
中的 *,因为标签大小需要有效 *),结果-同样是system font / bold / 60
,行数:0
,约束为w: 300.0, h: 160.0
:我们看起来很不错
但有两个问题…
首先,这段代码计算标签边界的“最佳拟合”点大小,如果我们将文本更改为“friend”:
我们最终得到了一个
111
的点大小--我假设这不是你的目标。所以,让我们做一个小小的修改:
现在我们可以用
label.fitTextToBounds(maxPointSize: 60.0)
调用它,结果是:第二个问题是扩展不考虑多行标签...如果我们将字符串更改为“友谊is good”,我们会得到:
所以,让我们试着改变一下……我们将把字符串分割成单词,并找到所需的最小点大小,以便 * 最长的单个单词 * 适合宽度:
我们看起来更好了
不幸的是,如果我们使用这个文本-“友谊对世界上的每个人都有好处”-字符串将超过标签的高度:
所以,让我们*也实现自动收缩:
然后...
除非我误解了你的任务,或者你有额外的要求,那可能是一个解决方案。
下面是一个使用上述扩展的控制器示例: