在方根符号的屋顶

时间:2013-10-11 02:15:01

标签: ios uilabel

我想写一个UILabel,它可以打印带有屋顶的平方根表达式,而不仅仅是一个简单的√x。 x上应该有一条线,好像它写在纸上一样。

1 个答案:

答案 0 :(得分:5)

使用Quartz 2D(QuartzCore框架),您可以在其上绘制线条:

因此,给定

self.label.text = @"√23+45";
[self addSquareRootTopTo:self.label];

这会在符号后面的字符上画一条线:

- (void)addSquareRootTopTo:(UILabel *)label
{
    NSRange range = [label.text rangeOfString:@"√"];
    if (range.location == NSNotFound)
        return;

    NSString *stringThruSqrtSymbol  = [label.text substringToIndex:range.location + 1];
    NSString *stringAfterSqrtSymbol = [label.text substringFromIndex:range.location + 1];

    CGSize sizeThruSqrtSymbol;
    CGSize sizeAfterSqrtSymbol;

    // get the size of the string given the label's font

    if ([stringThruSqrtSymbol respondsToSelector:@selector(sizeWithAttributes:)])
    {
        // for iOS 7

        NSDictionary *attributes = @{NSFontAttributeName : label.font};

        sizeThruSqrtSymbol  = [stringThruSqrtSymbol sizeWithAttributes:attributes];
        sizeAfterSqrtSymbol = [stringAfterSqrtSymbol sizeWithAttributes:attributes];
    }
    else
    {
        // for earlier versions of iOS

        sizeThruSqrtSymbol  = [stringThruSqrtSymbol sizeWithFont:label.font];
        sizeAfterSqrtSymbol = [stringAfterSqrtSymbol sizeWithFont:label.font];
    }

    // create path for line over the stuff after the square root sign

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(label.frame.origin.x + sizeThruSqrtSymbol.width, label.frame.origin.y)];
    [path addLineToPoint:CGPointMake(label.frame.origin.x + sizeThruSqrtSymbol.width + sizeAfterSqrtSymbol.width, label.frame.origin.y)];

    // now add that line to a CAShapeLayer

    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.path = path.CGPath;
    layer.lineWidth = 1.0;
    layer.strokeColor = [[UIColor blackColor] CGColor];
    layer.fillColor = [[UIColor clearColor] CGColor];
    [self.view.layer addSublayer:layer];
}

这产生了一个不太令人满意的差距:

enter image description here

你可以玩这个来轻推方形根符号的顶部,但另一种方法是使用Quartz 2D绘制整个平方根符号。因此,从标签的text值中取出平方根符号:

self.label.text = @"23+45";
[self addSquareRootTo:self.label];

然后在Quartz 2D中绘制整个平方根符号:

static CGFloat const part1 = 0.12;  // tiny diagonal will be 12% of the height of the text frame
static CGFloat const part2 = 0.35;  // medium sized diagonal will be 35% of the height of the text frame

- (void)addSquareRootTo:(UILabel *)label
{
    CGSize size;

    if ([label.text respondsToSelector:@selector(sizeWithAttributes:)])
    {
        NSDictionary *attributes = @{NSFontAttributeName : label.font};

        size = [label.text sizeWithAttributes:attributes];
    }
    else
    {
        size = [label.text sizeWithFont:label.font];
    }

    UIBezierPath *path = [UIBezierPath bezierPath];

    // it's going to seem strange, but it's probably easier to draw the square root size
    // right to left, so let's start at the top right of the text frame

    [path moveToPoint:CGPointMake(label.frame.origin.x + size.width, label.frame.origin.y)];

    // move to the top left

    CGPoint point = CGPointMake(label.frame.origin.x, label.frame.origin.y);
    [path addLineToPoint:point];

    // now draw the big diagonal line down to the bottom of the text frame (at 15 degrees)

    point.y += size.height;
    point.x -= sinf(15 * M_PI / 180) * size.height;
    [path addLineToPoint:point];

    // now draw the medium sized diagonal back up (at 30 degrees)

    point.y -= size.height * part2;
    point.x -= sinf(30 * M_PI / 180) * size.height * part2;
    [path addLineToPoint:point];

    // now draw the tiny diagonal back down (again, at 30 degrees)

    point.y += size.height * part1;
    point.x -= sinf(30 * M_PI / 180) * size.height * part1;
    [path addLineToPoint:point];

    // now add the whole path to our view

    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.path = path.CGPath;
    layer.lineWidth = 1.0;
    layer.strokeColor = [[UIColor blackColor] CGColor];
    layer.fillColor = [[UIColor clearColor] CGColor];
    [self.view.layer addSublayer:layer];
}

看起来好一点:

enter image description here

显然,您可以按照您想要的任何方式实现此目的(使用上述任一方法,或者可能更好,将UIView子类化为drawRect中的此类或其CoreGraphics等效项,但它说明了自己绘制平方根符号的想法。


顺便说一句,如果使用之前的Xcode版本5,您必须手动将QuartzCore.framework添加到项目中,然后包含相应的标题:

#import <QuartzCore/QuartzCore.h>