我已经在互联网上搜索了一段时间,以获取有关如何改变UIKit中字体的字母间距/字距调整的信息。
我担心的是,就像使用自己的自定义字体一样,你根本就不能。这将是一个可怕的消息。
我知道Apple正在通过这些限制来保护我们免受糟糕的设计,但它们也阻止我们实现真正优秀的设计。
人们建议我做什么?
使用带有标准字距调整的字体,人们可能不会注意到差异。
找到某人的黑客入门课程,以便在用辛苦赚来的现金分手后获得用户应得的外观。
使用我忽略的方法,并与UIKit一起做这件事,向那个传授这隐藏知识的人承诺我永远的感激。
答案 0 :(得分: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需要知道字体的渲染才能显示光标。从来没有找到解决方案......
答案 1 :(得分: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]);
}
答案 2 :(得分:3)
您可以使用Quartz 2D完成所需的操作。具体来说,CGContextSetCharacterSpacing
属性可以控制字母之间的间距。虽然我不确定是否会做错。
答案 3 :(得分: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]);
}
答案 4 :(得分: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);