系统字体“Hiragino Sans”用剪裁的上升器和下降器显示 [英] System font "Hiragino Sans" is show with clipped ascender and descenders

查看:148
本文介绍了系统字体“Hiragino Sans”用剪裁的上升器和下降器显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在我的应用程序中使用iOS的系统字体Hiragino Sans W3,但无论我选择哪种尺寸/款式或 UILabel 的尺寸,字体的上升和下降始终显示为剪辑:

I need to use the iOS's system font "Hiragino Sans W3" in my app, but no matter which size/style or the UILabel's dimensions I choose, the font's ascenders and descenders always appear clipped:

看来这可以通过创建 UILabel 的子类来修复,并覆盖方法 textRectForBounds:limitedToNumberOfLines:返回正确的价值。所以下面的代码......

It seems that this can this fixed by creating a subclass of UILabel and overwriting method textRectForBounds:limitedToNumberOfLines: to return the "correct" value. So the following code...

- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines
{
    CGRect result = [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
    result = CGRectInset(result, 0, -5);
    return result;
}

...导致ascender和descenders不再被剪裁:

...results in both the ascender and descenders not being clipped anymore:

我知道也可以调整字体上升和使用外部编辑器的下降位置。 但这是一个系统字体,如果没有任何修改它不能正常工作吗?这里有什么我想念的吗?

I know it's also possible to adjust font ascender and descender positions using an external editor. But this is a system font, shouldn't it work correctly without any modifications? Is there something I'm missing here?

提前感谢您的答案。

推荐答案

我认为这个问题实际上归结为字体本身(Hiragino Sans)。使用字体编辑器可以看到字形超出了上升和下降值,iOS似乎将其视为显示文本的垂直边界框。

I think this issue really boils down to the font itself ("Hiragino Sans"). Using a font editor it is possible to see that the glyphs go beyond the ascender and descender values, which is what iOS seems to assume as the vertical "bounding box" for displayed text.

由于缺乏更好的解决方案,我一直在使用(非常难看)hack来修改 UIFont 只读属性的值 ascender lineHeight

For the lack of a better solution, I've been using a (pretty ugly) hack which modifies the values for UIFont read-only properties ascender and lineHeight.

文件 UIFont +对齐.h

#import <UIKit/UIKit.h>

@interface UIFont (Alignment)

- (void)ensureCorrectFontAlignment;

@end

文件 UIFont +对齐。 m

#import "UIFont+Alignment.h"
#import <objc/runtime.h>
#import <objc/message.h>

static NSHashTable *adjustedFontsList;

@implementation UIFont (Alignment)

- (void)ensureCorrectFontAlignment
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        adjustedFontsList = [NSHashTable hashTableWithOptions:NSHashTableWeakMemory];
    });

    @synchronized (adjustedFontsList) {

        if ([adjustedFontsList containsObject:self]) {
            return;
        }
        else if ([self.fontName containsString:@"Hiragino"]) {

            SEL originalAscenderSelector = @selector(ascender);
            Method originalAscenderMethod = class_getInstanceMethod([UIFont class], originalAscenderSelector);
            SEL originalLineHeightSelector = @selector(lineHeight);
            Method originalLineHeightMethod = class_getInstanceMethod([UIFont class], originalLineHeightSelector);

            id result = method_invoke(self, originalAscenderMethod, nil);
            CGFloat originalValue = [[result valueForKey:@"ascender"] floatValue];
            [result setValue:@(originalValue * 1.15) forKey:@"ascender"];

            result = method_invoke(self, originalLineHeightMethod, nil);
            originalValue = [[result valueForKey:@"lineHeight"] floatValue];
            [result setValue:@(originalValue * 1.25) forKey:@"lineHeight"];

            [adjustedFontsList addObject:self];
        }
    }
}

@end

要应用,只需导入标题并在创建新的字体实例后调用 [myUIFont ensureCorrectFontAlignment]

To apply, just import the header and invoke [myUIFont ensureCorrectFontAlignment] after creating a new font instance.

这篇关于系统字体“Hiragino Sans”用剪裁的上升器和下降器显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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