I wanted to display a triangle shaped view in a UITableView cell like this.

I managed to accomplish this using the blow code.
import UIKit
class TriangleView: UIView {
    override func drawRect(rect: CGRect) {
        let width = self.layer.frame.width
        let height = self.layer.frame.height
        let path = CGPathCreateMutable()
        CGPathMoveToPoint(path, nil, 0, 0)
        CGPathAddLineToPoint(path, nil, width, 0)
        CGPathAddLineToPoint(path, nil, 0, height)
        CGPathAddLineToPoint(path, nil, 0, 0)
        CGPathCloseSubpath(path)
        let mask = CAShapeLayer()
        mask.frame = self.layer.bounds
        mask.path = path
        self.layer.mask = mask
        let shape = CAShapeLayer()
        shape.frame = self.bounds
        shape.path = path
        shape.fillColor = UIColor.clearColor().CGColor
        self.layer.insertSublayer(shape, atIndex: 0)
    }
}
While I was searching how to create shapes in UIViews, I discovered that you could use UIBezierPath to do the same. So I tried replicating the same thing using UIBezierPath.
let path = UIBezierPath()
path.moveToPoint(CGPoint(x: 0, y: 0))
path.moveToPoint(CGPoint(x: width, y: 0))
path.moveToPoint(CGPoint(x: 0, y: height))
path.moveToPoint(CGPoint(x: 0, y: 0))
path.closePath()
let mask = CAShapeLayer()
mask.frame = self.bounds
mask.path = path.CGPath
self.layer.mask = mask
let shape = CAShapeLayer()
shape.frame = self.bounds
shape.path = path.CGPath
shape.fillColor = UIColor.clearColor().CGColor
self.layer.insertSublayer(shape, atIndex: 0)
But this simply does't work. No shape is getting displayed.
Do I need to do anything extra in order to get this working?
A UIBezierPath object combines the geometry of a path with attributes that describe the path during rendering. You set the geometry and attributes separately and can change them independent of one another. After you have the object configured the way you want it, you can tell it to draw itself in the current context.
A layer that draws a cubic Bezier spline in its coordinate space.
You're making this harder than it needs to be. You only need to add a shape layer with a path, and set the fillColor of that layer. The main reason your code doesn't work though, is because you're using moveToPoint for all you lines instead of addLineToPoint for all but the first one.
class TriangleView: UIView {
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    override init(frame: CGRect) {
        super.init(frame: frame)
        let path = UIBezierPath()
        path.moveToPoint(CGPoint(x: 0, y: 0))
        path.addLineToPoint(CGPoint(x: frame.size.width, y: 0))
        path.addLineToPoint(CGPoint(x: 0, y: frame.size.height))
        path.closePath()
        let shape = CAShapeLayer()
        shape.frame = self.bounds
        shape.path = path.CGPath
        shape.fillColor = UIColor.blueColor().CGColor
        self.layer.addSublayer(shape)
    }
}
The problem should be the mask on layer and the color of shape.
The following code work for me.
class TriangleView: UIView {
    override func drawRect(rect: CGRect) {
        let width:CGFloat = bounds.width/9
        let height:CGFloat = bounds.width/9
        let path = UIBezierPath()
        path.moveToPoint(bounds.origin)
        path.addLineToPoint(CGPoint(x: width, y: bounds.origin.y))
        path.addLineToPoint(CGPoint(x: bounds.origin.x, y: height))
        // closePath will connect back to start point
        path.closePath()
        let shape = CAShapeLayer()
        shape.path = path.CGPath
        shape.fillColor = UIColor.blueColor().CGColor
        self.layer.insertSublayer(shape, atIndex: 0)
        // Setting text margin
        textContainerInset = UIEdgeInsetsMake(8, width, 8, 0)
    }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With