15

UIKit 内のフォントの文字間隔/カーニングを変更する方法についての情報を求めて、しばらくの間インターネットを精査してきました。

私が恐れているのは、独自のカスタム フォントを使用するのと同じように、単純にできないことです。これは恐ろしいニュースです。

Apple がこれらの制約によって悪いデザインから私たちを守っていることは知っていますが、本当に優れたデザインを実装することも妨げています。

人々は私に何をするように勧めますか?

  1. 標準のカーニングでフォントを使用すると、人々はおそらく違いに気付かないでしょう.

  2. 誰かのハッキングされたクラスを見つけて、苦労して稼いだ現金を手放した後、ユーザーにふさわしい外観を手に入れましょう。

  3. 私がなんとなく見落としていた方法をUIKitで実行し、この隠された知識の塊を伝えてくれた人に永遠の感謝を誓います.

4

5 に答える 5

4

UITextFieldで同じことをしようとして、Googleからここに着陸しました。以下のUILabelで一般的に機能するものを実装しました。

@interface AdjustableUILable : UILabel {
    CGFloat characterSpacing;
}

@property CGFloat characterSpacing;

@end


@implementation AdjustableUILable

@synthesize characterSpacing;

- (void)drawTextInRect:(CGRect)rect
{    
    if (characterSpacing)
    {
        // Drawing code
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGFloat size = self.font.pointSize;

        CGContextSelectFont (context, [self.font.fontName UTF8String], size, kCGEncodingMacRoman);
        CGContextSetCharacterSpacing (context, characterSpacing);
        CGContextSetTextDrawingMode (context, kCGTextFill);

        // Rotate text to not be upside down
        CGAffineTransform xform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
        CGContextSetTextMatrix(context, xform);
        const char *cStr = [self.text UTF8String];
        CGContextShowTextAtPoint (context, rect.origin.x, rect.origin.y + size, cStr, strlen(cStr));
    }
    else
    {
        // no character spacing provided so do normal drawing
        [super drawTextInRect:rect];
    }
}

@end

次に、それを使用するには、viewDidLoadなどでラベルを設定するだけです

- (void)viewDidLoad
{
        myLabel.characterSpacing = 2; // point size
}

UITextFieldで試してみましたが、残念ながら、ユーザーがフィールドを編集した後に文字間隔を追加するだけです。-drawTextInRect は、-textFieldShouldEndEditing デリゲート メソッドの後にのみ呼び出されます。他のフォーラムから、これは UITextField がカーソルを表示するためにフォントのレンダリングを知る必要があるためであると示唆されました。その部分の解決策を見つけたことはありません...

于 2011-10-10T20:10:07.997 に答える
4

受け入れられた回答では多くの書式設定が失われ、user363349 の回答はほとんど役に立ちましたが、テキストの配置は機能しませんでした。それを修正するためにコードを修正しました:

- (void) drawRect:(CGRect)rect
{
    // Drawing code
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSelectFont (context, [self.font.fontName cStringUsingEncoding:NSASCIIStringEncoding], self.font.pointSize, kCGEncodingMacRoman);
    CGContextSetCharacterSpacing(context, characterSpacing);
    CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
    CGAffineTransform myTextTransform = CGAffineTransformScale(CGAffineTransformIdentity, 1.f, -1.f );

    CGContextSetTextMatrix (context, myTextTransform);

    // draw 1 but invisbly to get the string length.
    CGPoint p =CGContextGetTextPosition(context);
    float centeredY = (self.font.pointSize + (self.frame.size.height- self.font.pointSize)/2)-2;
    CGContextShowTextAtPoint(context, 0, centeredY, [self.text cStringUsingEncoding:NSASCIIStringEncoding], [self.text length]);
    CGPoint v =CGContextGetTextPosition(context);

    // calculate width and draw second one.
    float width = v.x - p.x;
    float destX = 0;

    // calculate X position based on alignment
    if([self textAlignment] == UITextAlignmentLeft){
        destX = 0;
    }else if([self textAlignment] == UITextAlignmentCenter){
        destX = (self.frame.size.width- width)/2;
    }else if([self textAlignment] == UITextAlignmentRight){
        destX = self.frame.size.width - width;
    }
    CGContextSetFillColorWithColor(context, [self.textColor CGColor]);
    CGContextShowTextAtPoint(context, destX, centeredY, [self.text cStringUsingEncoding:NSASCIIStringEncoding], [self.text length]);
}
于 2012-08-18T21:16:01.100 に答える
3

Quartz 2D を使用して、必要なことを実行できる場合があります。具体的には、CGContextSetCharacterSpacingプロパティは文字間の間隔を制御できます。ただし、カーニングについてはわかりません。

Quartz 2D プログラミング ガイド: テキスト

于 2009-06-30T16:26:28.880 に答える
3

文字間隔を変更するために UILabel を拡張しました。これにより、ボックスが機能し、フォント、テキスト、色などが UILabel 自体から取得されます (適切なコーディング!)。

お気づきかもしれませんが、最初はクリア カラーで 2 回テキストを描画しています。これは、ラベルのテキストを自動的に中央揃えにするためです。これは非効率的かもしれませんが、自動的に中央揃えになるのはいいことではありませんか?

楽しみ!

@interface RALabel : UILabel {
}
@end  

@implementation RALabel 

- (void) drawRect:(CGRect)rect 
{

    // Drawing code

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSelectFont (context, [self.font.fontName cStringUsingEncoding:NSASCIIStringEncoding], self.font.pointSize, kCGEncodingMacRoman);
    CGContextSetCharacterSpacing(context, 1);
    CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
    CGAffineTransform myTextTransform = CGAffineTransformScale(CGAffineTransformIdentity, 1.f, -1.f );
    CGContextSetTextMatrix (context, myTextTransform);

    // draw 1 but invisbly to get the string length.
    CGPoint p =CGContextGetTextPosition(context);
    float centeredY = (self.font.pointSize + (self.frame.size.height- self.font.pointSize)/2)-2;
    CGContextShowTextAtPoint(context, 0, centeredY, [self.text cStringUsingEncoding:NSASCIIStringEncoding], [self.text length]);
    CGPoint v =CGContextGetTextPosition(context);

    // calculate width and draw second one.
    float width = v.x - p.x;
    float centeredX =(self.frame.size.width- width)/2;
    CGContextSetFillColorWithColor(context, [self.textColor CGColor]);
    CGContextShowTextAtPoint(context, centeredX, centeredY, [self.text cStringUsingEncoding:NSASCIIStringEncoding], [self.text length]);

}
于 2011-07-29T16:43:56.307 に答える
1

CGContextShowTextメソッドの主な問題-それらはASCII文字列のみを表示します。UTF文字列を表示するには、文字列記号をグリフにマップしてグリフを表示する必要があります。

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSelectFont (context, [self.font.fontName cStringUsingEncoding:NSASCIIStringEncoding], self.font.pointSize, kCGEncodingMacRoman);
    CGContextSetCharacterSpacing(context, characterSpacing);
    CGContextSetFillColorWithColor(context, [self.textColor CGColor]);
    CGAffineTransform myTextTransform = CGAffineTransformScale(CGAffineTransformIdentity, 1.f, -1.f );
    CGContextSetTextMatrix (context, myTextTransform);

    CGGlyph glyphs[self.text.length];
    CTFontRef fontRef = CTFontCreateWithName((CFStringRef)self.font.fontName, self.font.pointSize, NULL);
    CTFontGetGlyphsForCharacters(fontRef, (const unichar*)[self.text cStringUsingEncoding:NSUnicodeStringEncoding], glyphs, self.text.length);
    float centeredY = (self.font.pointSize + (self.frame.size.height- self.font.pointSize)/2)-2;
    CGContextShowGlyphsAtPoint(context, rect.origin.x, centeredY, (const CGGlyph *)glyphs, self.text.length);
于 2012-08-22T09:42:31.647 に答える