问题:
UILabel
可能会剪裁斜体(倾斜)字符,甚至剪裁左右边缘的脚本。以下屏幕截图显示了该问题。在左边,'j' 的下降部分被剪掉;在右边缘,“l”的上升部分被剪掉了。我意识到这很微妙,并不是每个人都会关心(但是,字体越大,问题越严重)。
这是一个使用 Zapfino 的不太微妙的示例,尺寸为 22。请注意木星中的“j”看起来几乎像一个“i”:
在上面的示例中,标签的背景颜色为橙色,文本左对齐,标签保持其固有内容大小。
这是 UILabel
的默认行为,多个版本的 iOS 都是这样(所以我不期望 Apple 会修复)。
我尝试过的:
将标签的 clipsToBounds
属性设置为 NO
并不能解决问题。我还知道我可以在标签上设置固定宽度约束,以便在后缘为文本留出更多空间。但是,固定宽度约束不会为上例中的“j”提供更多空间。
我将使用利用 Auto Layout 和标签的 alignmentRectInsets
的解决方案来回答我自己的问题。
最佳答案
当文本左对齐时,顶部标签显示 UILabel
的默认行为,即标签保持其固有内容大小。底部标签是 UILabel
的一个简单(几乎是微不足道的)子类。底部标签不夹住 'j' 或 'l';相反,它为文本在左右边缘提供了一些呼吸空间,而无需居中对齐文本(糟糕)。
虽然标签本身并没有在屏幕上对齐,但它们的文本确实对齐了;而且,在 IB 中,标签的左边缘实际上是对齐的,因为我重写了 UILabel
子类中的 alignmentRectInsets
。
这是配置两个标签的代码:
#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
子类的实现:
#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
无需编辑字体文件,无需使用 Core Text;对于那些使用 iOS 6+ 和自动布局的用户来说,这只是一个相对简单的 UILabel
子类。
更新:
Augie 注意到我原来的解决方案阻止了多行文本的自动换行。我通过使用 drawInRect:
而不是 drawAtPoint:
在标签的 drawRect:
方法中绘制文本来解决这个问题。
截图如下:
顶部标签是一个普通的 UILabel
。底部标签是一个 NonClippingLabel
,具有极端的间距设置以适应尺寸为 22.0 的 Zapfino。两个标签都使用自动布局左右对齐。
关于ios - UILabel 在内容的左右边缘剪裁斜体(倾斜)文本(iOS 6+),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20985085/