Cocoa Touch (iOS) Graphics Context Drawing 如何做对角?
How to do corners right with Cocoa Touch (iOS) Graphics Context Drawing?
我只是在试验,习惯在 iOS 上使用 Quartz 2D 绘图。我使用 Graphics Context move(to:) 和 addLine(_:CGPoint) 函数绘制了三个偏移正方形(仅周边线)。考虑下图的结果:
我只显示了顶部,但足以记录我的问题。您可以看到每个方块的左上角都不完整(尖锐的方角),而右上角看起来还不错。两个底角和右上角一样,完全符合我的预期。
因此,我添加这些线(宽度设置为 3.0)的起始位置是使用 Graphics Context move(to: CGPoiint) 定位的左上角。只需调用 addLine(_:CGPoint) 方法即可到达每个后续角点。
那么,我做错了什么导致如图所示的 "broken" 角。我如何让左上角看起来像所有其他角一样?
代码生成图
override func draw(_ rect: CGRect) {
let colors: [(CGFloat,CGFloat,CGFloat)] =
[(1.0,0.0,0.0),(0.25,1.0,0.5),(0.5,0.5,1.0)]
let c = UIGraphicsGetCurrentContext()!
c.setLineWidth(3.0)
var dx = 0
var dy = 0
for q in 1...3 {
c.move(to:CGPoint(x:dx+50, y:dy+50))
c.addLine(to:CGPoint(x: dx+200, y: dy+50))
c.addLine(to:CGPoint(x: dx+200, y: dy+200))
c.addLine(to:CGPoint(x: dx+50,y: dy+200))
c.addLine(to:CGPoint(x: dx+50,y: dy+50))
c.setStrokeColor(
red:colors[q-1].0
,green:colors[q-1].1
,blue:colors[q-1].2,alpha:1.0)
c.strokePath()
dx += 20
dy += 20
}
}
伪像是由较粗的线宽引起的。您给出的所有尺寸都是针对每条线的中心。由于您给出的线宽为 3,因此每条线在中心线的每一侧填充 1.5 磅。
您可以在第一个和最后一个坐标中考虑到这一点,但这很容易出错并且取决于线宽。
更好的解决方案是使用 closePath()
而不是添加最后一行。
c.move(to:CGPoint(x:dx+50, y:dy+50))
c.addLine(to:CGPoint(x: dx+200, y: dy+50))
c.addLine(to:CGPoint(x: dx+200, y: dy+200))
c.addLine(to:CGPoint(x: dx+50,y: dy+200))
//c.addLine(to:CGPoint(x: dx+50,y: dy+50)) // not needed any more
c.closePath()
closePath()
将从路径的最后一点到第一点画一条直线。这也涉及在第一个点位置的连接处正确填充那个小工件。
最简单的解决方案是使用 UIBezierPath
绘制矩形,但全部手动完成是学习的好方法。
我只是在试验,习惯在 iOS 上使用 Quartz 2D 绘图。我使用 Graphics Context move(to:) 和 addLine(_:CGPoint) 函数绘制了三个偏移正方形(仅周边线)。考虑下图的结果:
我只显示了顶部,但足以记录我的问题。您可以看到每个方块的左上角都不完整(尖锐的方角),而右上角看起来还不错。两个底角和右上角一样,完全符合我的预期。
因此,我添加这些线(宽度设置为 3.0)的起始位置是使用 Graphics Context move(to: CGPoiint) 定位的左上角。只需调用 addLine(_:CGPoint) 方法即可到达每个后续角点。
那么,我做错了什么导致如图所示的 "broken" 角。我如何让左上角看起来像所有其他角一样?
代码生成图
override func draw(_ rect: CGRect) {
let colors: [(CGFloat,CGFloat,CGFloat)] =
[(1.0,0.0,0.0),(0.25,1.0,0.5),(0.5,0.5,1.0)]
let c = UIGraphicsGetCurrentContext()!
c.setLineWidth(3.0)
var dx = 0
var dy = 0
for q in 1...3 {
c.move(to:CGPoint(x:dx+50, y:dy+50))
c.addLine(to:CGPoint(x: dx+200, y: dy+50))
c.addLine(to:CGPoint(x: dx+200, y: dy+200))
c.addLine(to:CGPoint(x: dx+50,y: dy+200))
c.addLine(to:CGPoint(x: dx+50,y: dy+50))
c.setStrokeColor(
red:colors[q-1].0
,green:colors[q-1].1
,blue:colors[q-1].2,alpha:1.0)
c.strokePath()
dx += 20
dy += 20
}
}
伪像是由较粗的线宽引起的。您给出的所有尺寸都是针对每条线的中心。由于您给出的线宽为 3,因此每条线在中心线的每一侧填充 1.5 磅。
您可以在第一个和最后一个坐标中考虑到这一点,但这很容易出错并且取决于线宽。
更好的解决方案是使用 closePath()
而不是添加最后一行。
c.move(to:CGPoint(x:dx+50, y:dy+50))
c.addLine(to:CGPoint(x: dx+200, y: dy+50))
c.addLine(to:CGPoint(x: dx+200, y: dy+200))
c.addLine(to:CGPoint(x: dx+50,y: dy+200))
//c.addLine(to:CGPoint(x: dx+50,y: dy+50)) // not needed any more
c.closePath()
closePath()
将从路径的最后一点到第一点画一条直线。这也涉及在第一个点位置的连接处正确填充那个小工件。
最简单的解决方案是使用 UIBezierPath
绘制矩形,但全部手动完成是学习的好方法。