4

除非绝对必要,否则我不想重新发明轮子,所以我想看看如何使用 Core Graphics 绘制这样的箭头:

在此处输入图像描述

有谁知道我该如何开始?这是我到目前为止所拥有的,但它绘制了一个正三角形而不是括号形状:

    CGPoint origin = CGPointMake(100, 20);
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:origin];
    [path addLineToPoint:CGPointMake(origin.x-10, origin.y-20)];
    [path addLineToPoint:CGPointMake(origin.x-10, origin.y+20)];
    [[UIColor redColor] set];
    [path fill];
4

4 回答 4

9

如果您按照@NSGod 的建议使用笔划进行绘制,则需要移动到上或下尖端,然后与箭头对齐,然后再到下或上尖端。如果你想要一个像你画的那样的 45 度角,你在坐标中添加或减去的量应该是相等的。

您还需要设置路径的线宽。这将需要与大小成比例。

CGPoint origin = CGPointMake(100, 20);

UIBezierPath *path = [UIBezierPath bezierPath];
// Upper tip
[path moveToPoint:CGPointMake(origin.x+20, origin.y-20)];
// Arrow head
[path addLineToPoint:CGPointMake(origin.x, origin.y)];
// Lower tip
[path addLineToPoint:CGPointMake(origin.x+20, origin.y+20)];

[[UIColor redColor] set];
// The line thickness needs to be proportional to the distance from the arrow head to the tips.  Making it half seems about right.
[path setLineWidth:10];
[path stroke];

结果是这样的形状。

上面代码绘制的箭头

如果你想填充,而不是描边——如果你想勾勒出你的箭头,这可能是必要的——你需要画出 6 个点,然后关闭路径。

于 2012-04-26T02:30:34.460 回答
3

问题的一个潜在部分是您使用fill的是stroke.

通过更改[path fill][path stroke],您将获得以下信息:

CGPoint origin = CGPointMake(100, 20);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:origin];
[path addLineToPoint:CGPointMake(origin.x - 10, origin.y - 20)];
[path addLineToPoint:CGPointMake(origin.x - 10, origin.y + 20)];
[[UIColor redColor] set];
// [path fill];
[path stroke];

在此处输入图像描述

这就提出了你的意思的origin问题。它实际上会转化为箭头点,而不是传统意义上的原点使用方式(意味着被绘制对象的左上角)。

如果要保留 的含义origin,则需要将代码修改为以下内容:

CGPoint origin = CGPointMake(100, 20);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(origin.x - 20, origin.y - 20)];
[path addLineToPoint:origin];
[path addLineToPoint:CGPointMake(origin.x - 20, origin.y + 20)];
path.lineWidth = 4.0;
[[UIColor redColor] set];
[path stroke];

或者,如果您想使用 的传统含义origin,您可以使用:

CGPoint origin = CGPointMake(100, 20);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:origin];
[path addLineToPoint:CGPointMake(origin.x + 20, origin.y + 20)];
[path addLineToPoint:CGPointMake(origin.x, origin.y + 20 * 2)];
path.lineWidth = 4.0;
[[UIColor redColor] set];
[path stroke];

这会产生以下结果:

在此处输入图像描述

于 2012-04-26T02:13:02.570 回答
1

这是一个与Swift 3.0兼容的类,其来源代码来自上面的@Dondragmer 的回答。

您可以更改:

  • lineHeight : CGFloat
  • 线条颜色:UIColor
  • 方向:Arrow.Direction(枚举与.up,.down,.left,.right)
类箭头:UIView {

    枚举方向{
        向上、向下、向左、向右
    }

    变种方向:方向=方向。右{
        设置{
            审查()
        }
    }

    var lineColor = UIColor.red {
        设置{
            审查()
        }
    }

    var lineWidth : CGFloat = 20 {
        设置{
            审查()
        }
    }

    功能审查(){
        设置需求显示()
    }


    静态函数 directionToRadians(_ 方向: Arrow.Direction) -> CGFloat{
        切换方向{
        案例.up:
            返回 Arrow.degreesToRadians(90)
        案例.down:
            返回 Arrow.degreesToRadians(-90)
        案例.左:
            返回 Arrow.degreesToRadians(0)
        案例.对:
            返回 Arrow.degreesToRadians(180)
        }
    }

    静态函数degreesToRadians(_度:CGFloat)-> CGFloat {
        返回度数 * CGFloat(M_PI) / 180
    }

    覆盖 func draw(_ rect: CGRect) {
        让 origin = CGPoint(x: 12, y: self.frame.height / 2)
        让路径 = UIBezierPath()
        path.lineJoinStyle = CGLineJoin.round
        path.move(to: CGPoint(x: origin.x + self.frame.width * (1/2), y: frame.height - 10))
        path.addLine(to: CGPoint(x: origin.x, y: origin.y))
        path.addLine(to: CGPoint(x: origin.x + self.frame.width * (1/2), y: 10))
        lineColor.set()
        path.lineWidth = 线宽
        path.stroke()
        self.backgroundColor = UIColor.clear
        self.transform = CGAffineTransform(rotationAngle: Arrow.directionToRadians(self.direction))
    }
}

现在你可以使用

这也与自动布局兼容。

let arrow = Arrow(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
arrow.lineWidth = 20
arrow.lineColor = UIColor.blue
arrow.direction = .up
于 2016-11-02T10:17:25.420 回答
0

我不是在电脑前写代码,但基本上你创建一个 CGMutablePath,然后添加

CGContextStrokePath(context);

您可以设置笔触宽度和线帽以获得所需的效果

于 2012-04-26T01:46:47.613 回答