在OSX绘制单行文本垂直居中

旧街凉风 提交于 2020-03-28 03:07:59

在iOS开发过程中,对单行文本的垂直居中似乎是一件非常easy的事情,直接用下面这段代码就可以完成:

123456789101112131415
@interface XXView : UIView@end@implementation XXView- (void)drawRect:(CGRect)rect{    UIFont *font = [UIFont fontWithName:@"Helvetica Neue" size:13];    NSDictionary *attributes = @{NSFontAttributeName:font,NSForegroundColorAttributeName:[UIColor redColor]};    NSAttributedString *title = [[NSAttributedString alloc] initWithString:@"我是垂直居中的"                                                                attributes:attributes];    [title drawAtPoint:CGPointMake(CGRectGetMidX(self.bounds)-title.size.width/2, CGRectGetMidY(self.bounds)-title.size.height/2)];}@end

在OSX平台上,我们一般会这样写这段代码:

12345678910111213141516171819202122
@interface XXView : NSView@end@implementation XXView- (void)drawRect:(NSRect)dirtyRect{    [[NSColor redColor] set];    NSFrameRect(self.bounds);        NSFont *font = [NSFont fontWithName:@"Helvetica Neue" size:13];    NSDictionary *attributes = @{NSFontAttributeName:font,NSForegroundColorAttributeName:[NSColor redColor]};    NSAttributedString *title = [[NSAttributedString alloc] initWithString:@"我位置有点儿偏下" attributes:attributes];        NSSize txtSize = title.size;    NSPoint drawPoint = NSMakePoint(NSMidX(self.bounds)-txtSize.width/2, NSMidY(self.bounds)-txtSize.height/2);            [title drawWithRect:NSMakeRect(drawPoint.x, drawPoint.y, txtSize.width, txtSize.height)                options:NSStringDrawingUsesLineFragmentOrigin];}@end

我们看到的效果将会是这样的:


这似乎并不符合预期,我尝试计算了NSFont的leading但仍然不能解决这个问题,经过对不同字体的对比,并绘制出NSAttributedString获得的size边框,就能发现NSFont在顶部总是会多出更多的空白区域,并且不仅仅只是字体leading所占用的区域.
知道问题之后,就算是找到了一个”曲线救国”解决办法,将原有的绘制方法改进为以下的代码:

1234567891011121314151617181920
- (void)drawRect:(NSRect)dirtyRect{    [[NSColor redColor] set];    NSFrameRect(self.bounds);        NSFont *font = [NSFont fontWithName:@"Helvetica Neue" size:13];    NSDictionary *attributes = @{NSFontAttributeName:font,NSForegroundColorAttributeName:[NSColor redColor]};    NSAttributedString *title = [[NSAttributedString alloc] initWithString:@"我是垂直居中的" attributes:attributes];        NSSize txtSize = title.size;    double topGap = txtSize.height - (font.ascender + fabs(font.descender));    NSPoint drawPoint = NSMakePoint(NSMidX(self.bounds)-txtSize.width/2, NSMidY(self.bounds)-txtSize.height/2);        if ([self isFlipped])        drawPoint.y -= topGap/2;    else        drawPoint.y += topGap/2;        [title drawAtPoint:drawPoint];}

最终可以获得我们预期的效果,并且支持flip模式:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!