除非绝对必要,否则我不想重新发明轮子,所以我想看看如何使用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];
答案 0 :(得分: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个点然后关闭路径。
答案 1 :(得分: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];
这会产生以下结果:
答案 2 :(得分:1)
这是一个 Swift 3.0 兼容类,其中包含来自@ Dondragmer上面答案的原始代码。
您可以更改:
class Arrow : UIView { enum Direction { case up, down, left, right } var direction : Direction = Direction.right { didSet { review() } } var lineColor = UIColor.red { didSet { review() } } var lineWidth : CGFloat = 20 { didSet { review() } } func review(){ setNeedsDisplay() } static func directionToRadians(_ direction: Arrow.Direction) -> CGFloat{ switch direction { case .up: return Arrow.degreesToRadians(90) case .down: return Arrow.degreesToRadians(-90) case .left: return Arrow.degreesToRadians(0) case .right: return Arrow.degreesToRadians(180) } } static func degreesToRadians(_ degrees: CGFloat) -> CGFloat { return degrees * CGFloat(M_PI) / 180 } override func draw(_ rect: CGRect) { let origin = CGPoint(x: 12, y: self.frame.height / 2) let path = 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 = 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
答案 3 :(得分:0)
我不是在电脑前编写代码,但基本上你创建了一个CGMutablePath,然后添加
CGContextStrokePath(context);
您可以设置所需效果的笔触宽度和线条上限