UILabel在内容的左右边缘剪切斜体(斜)文本(iOS 6+) [英] UILabel clipping italic (oblique) text at left and right edges of content ( iOS 6+)
问题描述
问题:
UILabel
可能会在左右边缘剪切斜体(斜)字符甚至脚本。以下屏幕截图显示了该问题。在左边缘,'j'的下降部分被剪掉;在右边缘,'l'的上升部分被剪掉。我意识到这是微妙的,并不是每个人都会关心(但是,更大的字体大小会使问题变得更糟)。
Problem:
UILabel
may clip italic (oblique) characters and even scripts at the left and right edges. The following screenshot displays the issue. At the left edge, the descender of the 'j' is clipped; at the right edge, the ascender of the 'l' is clipped. I realize this is subtle, and not everyone is going to care (however, the issue gets worse with larger font sizes).
这是使用Zapfino的一个不太精细的例子,大小为22.请注意,jupiter中的'j'看起来几乎像'i':
Here's a less subtle example using Zapfino, size 22. Note the 'j' in jupiter looks almost like an 'i':
在上面的示例中,标签的背景颜色为橙色,文本左对齐,标签保持其内在内容大小。
In the examples above, the background color of the label is orange, the text is left aligned, and the label maintains its intrinsic content size.
这是 UILabel
的默认行为,对于多个版本的iOS来说就是这样(所以我'我不希望Apple提供修复。
This is the default behavior of a UILabel
and its been that way for multiple versions of iOS (so I'm not expecting a fix from Apple).
我尝试了什么:
设置标签的 clipsToBounds
属性否
无法解决问题。我也知道我可以在标签上设置固定宽度约束,以便在后端为文本提供更多空间。但是,固定宽度约束不会给上面示例中的'j'提供更多空间。
What I have tried:
Setting the label's clipsToBounds
property to NO
does not resolve the issue. I'm also aware that I could set a fixed width constraint on the label to give the text more room at the trailing edge. However, a fixed width constraint would not give the 'j', in the example above, more room.
我将使用一个利用自动布局和标签 alignmentRectInsets的解决方案来回答我自己的问题
。
I'm going to answer my own question using a solution that leverages Auto Layout and the label's alignmentRectInsets
.
推荐答案
顶部标签显示 UILabel
的默认行为文本左对齐,标签保持其内在内容大小。底部标签是 UILabel
的简单(几乎是微不足道的)子类。底部标签不会剪切'j'或'l';相反,它给文本提供了一些在左右边缘呼吸的空间,而没有居中对齐文本(yuck)。
The top label shows the default behavior of a UILabel
when the text is left aligned that the label maintains its intrinsic content size. The bottom label is a simple (almost trivial) subclass of UILabel
. The bottom label does not clip the 'j' or the 'l'; instead, it gives the text some room to breathe at the left and right edges without center aligning the text (yuck).
虽然标签本身在屏幕上看起来没有对齐,但它们的文字却是看似对齐;而且,在IB中,标签的左边缘实际上是对齐的,因为我在 UILabel
子类中覆盖 alignmentRectInsets
。
Although the labels themselves don't appear aligned on screen, their text does appear aligned; and what's more, in IB, the labels actually have their left edges aligned because I override alignmentRectInsets
in a UILabel
subclass.
以下是配置两个标签的代码:
Here's the code that configures the two labels:
#import "ViewController.h"
#import "NonClippingLabel.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *topLabel;
@property (weak, nonatomic) IBOutlet NonClippingLabel *bottomLabel;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *string = @"jupiter ariel";
UIFont *font = [UIFont fontWithName:@"Helvetica-BoldOblique" size:28];
NSDictionary *attributes = @{NSFontAttributeName: font};
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:string attributes:attributes];
self.topLabel.attributedText = attrString;
self.bottomLabel.attributedText = attrString;
}
这是 NonClippingLabel $ c的实现$ c>子类:
#import <UIKit/UIKit.h>
@interface NonClippingLabel : UILabel
@end
@implementation NonClippingLabel
#define GUTTER 4.0f // make this large enough to accommodate the largest font in your app
- (void)drawRect:(CGRect)rect
{
// fixes word wrapping issue
CGRect newRect = rect;
newRect.origin.x = rect.origin.x + GUTTER;
newRect.size.width = rect.size.width - 2 * GUTTER;
[self.attributedText drawInRect:newRect];
}
- (UIEdgeInsets)alignmentRectInsets
{
return UIEdgeInsetsMake(0, GUTTER, 0, GUTTER);
}
- (CGSize)intrinsicContentSize
{
CGSize size = [super intrinsicContentSize];
size.width += 2 * GUTTER;
return size;
}
@end
不编辑字体文件,不使用核心文本;对于那些使用iOS 6+和自动布局的人来说,只是一个相对简单的 UILabel
子类。
No editing a font file, no using Core Text; just a relatively simple UILabel
subclass for those using iOS 6+ and Auto Layout.
更新:
Augie发现我的原始解决方案阻止了多行文字的自动换行。我通过使用 drawInRect:
而不是 drawAtPoint:
来修复该问题,以在标签的 drawRect:
方法。
Augie caught the fact that my original solution prevented word wrapping for multi-lined text. I fixed that issue by using drawInRect:
instead of drawAtPoint:
to draw the text in the label's drawRect:
method.
这是截图:
顶级标签是普通香草的UILabel
。底部标签是 NonClippingLabel
,带有极端的装订线设置,可容纳尺寸为22.0的Zapfino。两个标签都使用自动布局左右对齐。
The top label is a plain-vanilla UILabel
. The bottom label is a NonClippingLabel
with an extreme gutter setting to accommodate Zapfino at size 22.0. Both labels are left and right aligned using Auto Layout.
这篇关于UILabel在内容的左右边缘剪切斜体(斜)文本(iOS 6+)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!