UILabel在内容的左右边缘剪切斜体(斜)文本(iOS 6+) [英] UILabel clipping italic (oblique) text at left and right edges of content ( iOS 6+)

查看:671
本文介绍了UILabel在内容的左右边缘剪切斜体(斜)文本(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 子类:

#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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆