UILabel在内容的左右边缘剪切斜体(斜)文本(iOS 6+)

bil*_*tum 17 uilabel ios autolayout ios7

问题: UILabel可能会在左右边缘剪切斜体(斜)字符甚至脚本.以下屏幕截图显示了该问题.在左边缘,'j'的下降部分被剪掉; 在右边缘,'l'的上升部分被剪掉.我意识到这是微妙的,并不是每个人都会关心(但是,更大的字体大小会使问题变得更糟).

在此输入图像描述

这是使用Zapfino的一个不太微妙的例子,大小为22.请注意,jupiter中的'j'看起来几乎像'i':

在此输入图像描述

在上面的示例中,标签的背景颜色为橙色,文本左对齐,标签保持其内在内容大小.

这是a的默认行为,UILabel对于多个版本的iOS来说就是这样(所以我不期待Apple的修复).

我尝试过: 将标签的clipsToBounds属性设置为NO不能解决问题.我也知道我可以在标签上设置固定的宽度约束,使文本在后端有更多的空间.但是,固定宽度约束不会给上面示例中的'j'提供更多空间.

我将使用利用自动布局和标签的解决方案来回答我自己的问题alignmentRectInsets.

bil*_*tum 21

顶部标签显示了UILabel文本左对齐时标签保持其内在内容大小的默认行为.底部标签是一个简单的(几乎是微不足道的)子类UILabel.底部标签不会剪切'j'或'l'; 相反,它给文本提供了一些在左右边缘呼吸的空间,而没有居中对齐文本(yuck).

在此输入图像描述

虽然标签本身在屏幕上看起来没有对齐,但它们的文字看起来确实是对齐的; 而且,在IB中,标签实际上左边缘对齐,因为我alignmentRectInsetsUILabel子类中重写.

在此输入图像描述

这是配置两个标签的代码:

#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;     
}
Run Code Online (Sandbox Code Playgroud)

这是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
Run Code Online (Sandbox Code Playgroud)

没有编辑字体文件,没有使用Core Text; UILabel对于那些使用iOS 6+和Auto Layout 的人来说,这只是一个相对简单的子类.

更新:

Augie发现我的原始解决方案阻止了多行文本的自动换行.我通过使用drawInRect:而不是drawAtPoint:在标签的drawRect:方法中绘制文本来修复该问题.

这是一个截图:

在此输入图像描述

顶级标签是普通香草UILabel.底部标签是一个NonClippingLabel极端的天沟设置,以容纳22.0大小的Zapfino.两个标签使用"自动布局"左右对齐.

在此输入图像描述