I am trying to learn building custom shapes using UIBezierPath and I am trying to build a simple triangle. Below is the code I am using
class ViewController: UIViewController {
let customView = CustomTraingleView(frame: CGRectZero)
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(customView)
customView.frame = CGRect(origin: CGPoint(x: 150, y: 200), size: CGSize(width: 100, height: 100))
}
}
class CustomTraingleView: UIView
{
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.red
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
let viewSize = self.bounds.size
let path = UIBezierPath()
path.lineWidth = 3
path.move(to: CGPoint(x: frame.origin.x + viewSize.width/2, y: frame.origin.y + viewSize.height/2))
path.addLine(to: CGPoint(x: frame.origin.x + (3 * viewSize.width)/4, y: frame.origin.y + (3 * viewSize.height)/4))
path.addLine(to: CGPoint(x: frame.origin.x + viewSize.width/2, y: frame.origin.y + (3 * viewSize.height)/4))
UIColor.black.setStroke()
path.stroke()
path.close()
}
}
I am not seeing any shape getting rendered. I am seeing a red bgColor with the view I am adding.
Could someone please take a look at this and let me know what I am missing here
2
Answers
You have drawn the triangle relative to
frame.origin
, rather than tobounds.origin
.frame
, as you have set inviewDidLoad
isx: 150, y: 200
, so the triangle is will be drawn 150 points to the right, and 200 points below the top left corner of the red square. The red square is only 100×100 points, so that position is out of the bounds of the red square (and probably even off screen if your device is small), which is why you cannot see the triangle.In other words, in
CustomTraingleView.draw
, you are working in the coordinate system ofCustomTriangleView
, not the coordinate system of the view controller’s view.frame.origin
is the origin point of theCustomTriangleView
expressed in the coordinates of the superview’s coordinate system – the coordinates are relative to the superview’s origin. But you are drawing relative toCustomTraingleView
‘s origin here!Therefore, you should change all those
frame
s tobounds
:bounds.origin
is the origin point of the view expressed in the coordinates of the view’s own coordinate system, exactly what we need here. By default, this is (0, 0).And you should also close the path first, then stroke it. Otherwise you only get two sides of the triangle 🙂
Try this, declare your UIView:
this i how your triangle class looks like:
In viewDidLoad set your view attribute and set constraints:
This is the result