15

我已经在 Internet 上搜索了一段时间,以获取有关如何在 UIKit 中更改字体的字母间距/字距的信息。

我担心的是,就像使用自己的自定义字体一样,你根本做不到。这将是一个可怕的消息。

我知道 Apple 正在保护我们免受这些限制的糟糕设计,但它们也阻止我们实施真正伟大的设计。

人们建议我做什么?

  1. 使用带有标准字距的字体,人们可能无论如何都不会注意到差异。

  2. 找到某人的黑客课程,以获得用户在与他们辛苦赚来的现金分开后应得的外观。

  3. 使用我不知何故忽略的方法,并使用 UIKit 来做,向传授这些隐藏知识的人表示我永远的感激之情。

4

5 回答 5

4

我从谷歌来到这里,试图对 UITextField 做同样的事情。我在下面实现了一些对 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

我扩展了 UILabel 来改变字符间距。这应该可以解决问题,并从 UILabel 本身中提取字体、文本、颜色等(正确编码!)。

你可能会注意到我画了两次文字,第一次是用清晰的颜色。这是为了使标签中的文本自动居中。虽然这可能效率低下 - 自动居中不是很好吗?

享受!

@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 回答
3

您可以使用 Quartz 2D 做您需要的事情。具体来说,该CGContextSetCharacterSpacing属性可以控制字母之间的间距。不过,我不确定字距调整。

Quartz 2D 编程指南:文本

于 2009-06-30T16:26:28.880 回答
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 回答