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


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @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平台上,我们一般会这样写这段代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    - (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模式:
    vertical1

  • 相关阅读:
    NoHttp开源Android网络框架1.0.0之架构分析
    3种浏览器性能測试
    自己定义控件-画板,橡皮擦,刮刮乐
    android优化 清除无效代码 UCDetector
    iOS推送 (百度推送)
    C#中的协变OUT和逆变
    使用反射构造对象实例并动态调用方法
    用反射获取构造函数带参数的实例对象
    自己实现一个IOC(控制翻转,DI依赖注入)容器
    func 和action 委托的使用
  • 原文地址:https://www.cnblogs.com/xiao-love-meng/p/5757577.html
Copyright © 2020-2023  润新知