I'm creating a custom IBDesignable
control and I want to draw a set of squares in there. I have a draw(_ rect:)
method which does the following:
override func draw(_ rect: CGRect) {
// ... skipped ...
for i in 0 ..< 7 {
for j in 0 ... 6 {
let x = Double(i) * (cellSize + space)
let y = Double(j) * (cellSize + space)
let rectangle = CGRect(x: x, y: y, width: cellSize, height: cellSize)
let face = UIBezierPath(roundedRect: rectangle, cornerRadius: CGFloat(0))
face.fill()
}
}
}
This works just fine when I add the component into interface builder and I can see the squares. But when I run it in the simulator it draws rectangles but not squares:
This seems quite weird as width
is equal to height
. It works same way even if I draw with lines:
let face = UIBezierPath()
face.move(to: CGPoint(x: x, y: y))
face.addLine(to: CGPoint(x: x + cellSize, y: y))
face.addLine(to: CGPoint(x: x + cellSize, y: y + cellSize))
face.addLine(to: CGPoint(x: x, y: y + cellSize))
face.close()
or if I use regular not round corner rectangle:
let face = UIBezierPath(rect: rectangle)
Any ideas what could be wrong?
The problem is timing. The view is being drawn using squares, but then the interface is laid out and the view height is made a little smaller or its width is made a little larger. The drawing is cached — you have not set the view to be redrawn when its bounds change — so the drawing is now slightly distorted, as if a scale transform had been applied to it with a different horizontal value from the vertical value. Hence the squares are no longer square.