我正在尝试解决此问题,因为我正在处理的应用程序中有很多字体,因此当用户更改字体时,标签的大小会动态计算。
我的问题是,如果字体像下面的波纹管一样,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
是行不通的。
Here is sample code on Github.
Any help/advice is appreciated.
Even I don't have the time to test it, I'm pretty sure that the problem is that the label size is calculated from the advances. The advance is the amount of movement from one character's base point to the next ones. Typically for an italic font the advance can be smaller than the bounds. Therefore adding the advances will cut the end of the layout.
I.e. 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)
So I think that you have to add the difference between advance and bounding box of the last character, if the text is layout in an ideal way (no compression and so on).
To get both values, you have to call some CT functions:
// 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);
Typed in Safari.
加法:您在左侧有相同的问题:大写字母L的前进为0(第一个字符),但是边界框的值为负x。因此左侧被修剪。在那里也增加空间。(到目前为止更容易些。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句