我试图解决这个问题,因为在我正在处理的应用程序中我有很多字体,所以当用户更改字体时,标签的大小会被动态计算。
我遇到的问题是,如果字体是斜体,那么UILabel会被剪裁在最后:如下图所示:
这是我到目前为止所尝试的:
CGSize CTFramesetterSuggestFrameSizeWithConstraints ( CTFramesetterRef framesetter, CFRange stringRange, CFDictionaryRef frameAttributes, CGSize constraints, CFRange *fitRange );
- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options context:(NSStringDrawingContext *)context
- (CGSize)sizeWithAttributes:(NSDictionary<NSString *,id> *)attrs
sizeThatFits´ and
fitToSize` 由于应用程序中有很多字体,我需要动态设置标签的宽度,因此UILabel的子类化以及在drawFrameInRect
上添加更多的点是行不通的。
以下是Github上的示例代码。
感谢任何帮助/建议。
答案 0 :(得分:1)
CGSize size = [label.text sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17.0f]}];
CGSize adjustedSize = CGSizeMake(ceilf(size.width), ceilf(size.height));
并从adjustSize更新标签的宽度和高度。希望它能正常工作
答案 1 :(得分:1)
这对我有用。
func labelThatFits(_ title: String) -> UILabel {
let titleLabel = UILabel()
titleLabel.font = UIFont(name: fontName, size: 20)
titleLabel.text = title
titleLabel.textAlignment = .center
titleLabel.widthAnchor.constraint(equalToConstant: titleLabel.intrinsicContentSize.width + 10).isActive = true
return titleLabel
}
答案 2 :(得分:0)
我会在您的按钮和标签上使用自动布局,始终根据您选择标签的字体大小使其居中。
然后,删除updateLabel
方法中的所有代码。我不确定你为什么使用UITextview
并将爵士乐带入画面。如果您在故事板中单击标签并检查属性检查器并找到&#34; Autoshrink&#34;它应设置为&#34;最小字体大小&#34; NOT&#34;固定字体大小。&#34;
然后我会在您的标签上使用NSAttributedString
根据点击的按钮更改其大小和字体。
答案 3 :(得分:0)
我下载了你的GitHub项目,看来UILabel和UITextField肯定是以不同的方式计算文本的边界。所以,我首先尝试将UITextField上sizeToFit的结果大小分配给UILabel的大小。但是,这种方法打破了Strato字体。
在尝试了其他一些失败的方法之后,我记得斜体字体或多或少都是相同的角度。字体的斜体版本通常会将边界框的宽度增加与原始宽度相同的比例。
<强>更新强>
因此,您应该能够从宽度和字体大小派生斜体字符串的宽度。我在您的项目中尝试过这种方法,它适用于您列出的所有字体。我使用了以下公式:
CGRect calculatedRect = [attributedString boundingRectWithSize:CGSizeMake(CGFLOAT_MAX,CGFLOAT_MAX)选项:(NSStringDrawingUsesLineFragmentOrigin)context:nil];
calculatedRect.size.width = calculatedRect.size.width +(label.font.pointSize * 0.2);
由于这取决于斜体加入的宽度,因此斜体粗体字体(如Strata)会对宽度产生更大的影响。
显然,如果文本API被扩充以包含文本宽度的可靠计算,您将能够采用它。但是,如果您想要向后兼容,我提供的解决方法可能仍然是更好的选择。
我希望有所帮助!
答案 4 :(得分:0)
即使我没有时间对其进行测试,我也很确定问题是标签尺寸是根据进展来计算的。提前量是从一个角色的基点到下一个角色的移动量。通常对于斜体字体,前进可以小于边界。因此,添加预付款将缩短布局的结束。
即。 Baskerville-Italic H
:
(lldb) p bounds[0].size
(CGSize) $6 = (width=33.53515625, height=26.484375)
(lldb) p advances[0]
(CGSize) $7 = (width=30, height=0)
所以我认为你必须添加最后一个字符的advance和bounding框之间的区别,如果文本是理想的布局(没有压缩等等)。
要获得这两个值,您必须调用一些CT函数:
// What you probably have
CTFontRef font = …;
CFStringRef string = …;
CFAAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes);
// Get the character and glyph
CFIndex count = CFStringGetLength(string); // The length of the string
UniChar character;
CFStringGetCharacters( string, CFMakeRange( count-1, 1), &character );
CGGlyph glyph;
CTStringGetGlyphsForCharacters( font, &character, &glyph,1 );
// Get the advance
CGSize advance;
CTFontGetAdvancesForGlyphs( font, 0, &glyph, &advance, 1);
// Get the bounds
CGRect bounds;
CTFontGetAdvancesForGlyphs( font, 0, &glyph, &bounds, 1);
输入Safari。
添加:你在左侧遇到同样的问题:前进到大写L是0(第一个字符),但是边界框有一个负x。因此左侧被剪裁。在那里添加空间..(到目前为止更容易。)
答案 5 :(得分:0)
使用NSStringDrawingUsesDeviceMetrics
中的boundingRectWithSize:options:context:
可以获得更好的效果。
答案 6 :(得分:0)
1:使用当前选定的字体将文字设置为标签。
2:使用此方法
- (CGSize)getSizeforController:(id)view
{
UILabel *tempView =(UILabel *)view;
NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
context.minimumScaleFactor = 0.8;
float height = tempView.frame.size.height;
CGSize size=[tempView.text boundingRectWithSize:CGSizeMake(2000, height)options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName : tempView.font}context:context].size;
return size;
}
3:然后设置
CGSize newSize = [self.getSizeforController:self.lblYourLabel];
self.lblYourLabel.frame.size = newSize;
希望这对你有用。
答案 7 :(得分:0)
试试这个
CGSize lableWidth = CGSizeMake(300, CGFLOAT_MAX);
CGSize requiredSize = [yourLabel sizeWithFont:[UIFont fontWithName:@"FontName" size:17] constrainedToSize:lableWidth lineBreakMode:NSLineBreakByWordWrapping];
int calculatedHeight = requiredSize.height;