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


You have drawn the triangle relative to
frame.origin, rather than tobounds.origin.frame, as you have set inviewDidLoadisx: 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 100x100 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.originis the origin point of theCustomTriangleViewexpressed 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
frames tobounds:bounds.originis 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 :)