首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在内容的左右边缘使用UILabel裁剪斜体(斜体)文本( iOS 6+)

在内容的左右边缘使用UILabel裁剪斜体(斜体)文本( iOS 6+)
EN

Stack Overflow用户
提问于 2014-01-08 08:55:43
回答 4查看 4.6K关注 0票数 19

问题: UILabel可能会在左右边缘裁剪斜体(斜体)字符甚至脚本。下面的屏幕截图显示了该问题。在左边缘,'j‘的下降者被裁剪;在右边缘,'l’的升降者被裁剪。我意识到这是微妙的,并不是每个人都会关心(然而,更大的字体大小问题会变得更糟)。

下面是一个使用Zapfino的简单示例,大小为22。注意: jupiter中的'j‘看起来几乎像一个'i':

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

这是UILabel的默认行为,在iOS的多个版本中也是如此(所以我不指望苹果会对其进行修复)。

我尝试过的:将标签的clipsToBounds属性设置为NO并不能解决问题。我还意识到,我可以在标签上设置固定宽度约束,以便在尾部边缘给文本更多空间。但是,固定宽度约束不会给上面示例中的'j‘提供更多空间。

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-01-08 08:55:43

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

尽管标签本身在屏幕上不会对齐,但它们的文本确实会对齐;而且,在IB中,标签的左边缘实际上是对齐的,因为我覆盖了UILabel子类中的alignmentRectInsets

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

代码语言:javascript
复制
#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子类的实现:

代码语言:javascript
复制
#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

没有编辑字体文件,没有使用核心文本;只是一个相对简单的UILabel子类,用于那些使用iOS 6+和自动布局的人。

更新:

Augie注意到我最初的解决方案阻止了多行文本的自动换行。我修复了这个问题,使用drawInRect:而不是drawAtPoint:在标签的drawRect:方法中绘制文本。

这是一个截图:

最上面的标签是一款普通的UILabel。底部标签是一个NonClippingLabel,具有极端的间隔设置,以适应Zapfino的尺寸为22.0。两个标签都使用自动布局进行左对齐和右对齐。

票数 23
EN

Stack Overflow用户

发布于 2018-04-22 03:40:58

带有固定sizeThatFits方法的NonClippingLabel的Swift版本,来自于双叶答案。

代码语言:javascript
复制
class NonClippingLabel: UILabel {

    let gutter: CGFloat = 4

    override func draw(_ rect: CGRect) {
        super.drawText(in: rect.insetBy(dx: gutter, dy: 0))
    }

    override var alignmentRectInsets: UIEdgeInsets {
        return .init(top: 0, left: gutter, bottom: 0, right: gutter)
    }

    override var intrinsicContentSize: CGSize {
        var size = super.intrinsicContentSize
        size.width += gutter * 2

        return size
    }

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        let fixedSize = CGSize(width: size.width - 2 * gutter, height: size.height)
        let sizeWithoutGutter = super.sizeThatFits(fixedSize)

        return CGSize(width: sizeWithoutGutter.width + 2 * gutter,
                      height: sizeWithoutGutter.height)
    }

}
票数 4
EN

Stack Overflow用户

发布于 2018-07-10 09:00:29

要解决苹果的这个愚蠢的bug (我就是这么做的),一个简单的办法就是在字符串的末尾添加一个空格,以防止最后一个斜体字母被剪切。显然对多行标签没有帮助,或者剪切的第一个字母下降...

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20985085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档