2017-06-05 13 views
1

私のアプリでは、iOSのシステムフォント "Hiragino Sans W3"を使用する必要がありますが、サイズ/スタイルやUILabelのサイズフォントのアセンダとディセンダは常にクリッピング表示されます。これが、これが「正しい」値を返すようにする方法textRectForBounds:limitedToNumberOfLines:UILabelのサブクラスを作成し、上書きすることで固定できるようですシステムフォント "Hiragino Sans"はクリッパーされた昇順と降順で表示されます

enter image description here

。したがって、次のコード...

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

...もうクリッピングされていないアセンダとディセンダの両方で結果:

enter image description here

私はそれがフォントアセンダとディセンダ位置を調整することも可能です知っています外部エディタを使用します。 しかし、これはシステムフォントです。何も変更しなくても正しく動作するはずはありませんか?私がここで紛失しているものはありますか?

ご回答ありがとうございます。

+1

私はあなたにとってより良い答えを得たいと思っていますが、私が言うことができるのは、これを再現することができ、予期せぬことに同意したことです。 Appleにバグレポートを提出したいかもしれません。 – allocate

答えて

1

私はこの問題が実際にはフォント自体( "Hiragino Sans")にまで及ぶと思います。フォントエディタを使用すると、グリフがascenderとdescenderの値を超えて表示されることがわかります。これは、iOSが表示されたテキストの垂直「境界ボックス」として想定しているようです。

より良い解決策がないため、UIFontの読み取り専用プロパティascenderlineHeightの値を変更する(かなり醜い)ハックを使用しています。

UIFont+Alignment.h

ファイル:

#import <UIKit/UIKit.h> 

@interface UIFont (Alignment) 

- (void)ensureCorrectFontAlignment; 

@end 

ファイルUIFont+Alignment.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]を呼び出すだけ適用します。

関連する問題