iosswiftcgpath

UIView mask triangle


I would like to add a triangle mask pattern to the bottom and top edge of my UIView. Something like this:

virtual 'Harry Potter' ticket with triangle pattern at top and bottopm

So far I was only able to draw the bottom pattern:

Red box with triangle cutout pattern at bottom

let constant: CGFloat = 5
let width = rect.width
let height = rect.height

var p = CGPoint.zero
let path = UIBezierPath()
path.move(to: .zero)

p.x = width
path.addLine(to: p)
p.y = height
path.addLine(to: p)

var i = 0
var value = false
while Double(i) <= Double(width + 10) {
    value.toggle()
    if value {
        p.x -= constant
        p.y -= constant
        path.addLine(to: p)
    } else {
        p.x -= constant;
        p.y += constant;
        path.addLine(to: p)
    }
    i += 1
}
path.close()

let maskShape = CAShapeLayer()
maskShape.path = path.cgPath
layer.mask = maskShape

How can I create the view with the triangle pattern on the top and bottom edges?

Thank you


Solution

  • You have most of the logic.

    Think of having a pen drawing on a sheet of paper with coordinates.

     /\/\/\/\/\/\/\/\
    |                |
    |                |
    |                |
     \/\/\/\/\/\/\/\/
    

    So CGPoint.zero is top left and will be the start of our drawing.

    
        +    
         /\/\/\/\/\/\/\/\
        |                |
        |                |
        |                |
         \/\/\/\/\/\/\/\/
    
    
    var point = CGPoint.zero
    let path = UIBezierPath()
    path.move(to: point)
    

    So, let's draw the triangles.

    ----------------->
     /\/\/\/\/\/\/\/\
    |                |
    |                |
    |                |
     \/\/\/\/\/\/\/\/
    
    
    var i = 0
    var value = true
    while Double(i) <= Double(width + 10) {
        value.toggle()
        point.x += constant
        if value {
            point.y -= constant
        } else {
            point.y += constant;
        }
        path.addLine(to: point)
        i += 1
    }
    

    We are now at top right, so let's continue our drawing and let's go to bottom right:

     /\/\/\/\/\/\/\/\
    |                | |
    |                | |
    |                | |
     \/\/\/\/\/\/\/\/ ˇ 
    
    point = CGPoint(x: width, y: height)
    path.addLine(to: point)
    

    Now, we need the triangles until reaching bottom left:

     /\/\/\/\/\/\/\/\
    |                |
    |                |
    |                |
     \/\/\/\/\/\/\/\/
    <-----------------
    
    i = 0
    value = true
    while Double(i) <= Double(width + 10) {
        value.toggle()
        point.x -= constant
        if value {
            point.y += constant
        } else {
            point.y -= constant;
        }
        path.addLine(to: point)
        i += 1
    }
    

    Now, let's go back to starting point and close:

    ^   /\/\/\/\/\/\/\/\
    |  |                |
    |  |                |
    |  |                |
        \/\/\/\/\/\/\/\/
    
    point = CGPoint(x: 0, y: 0) //Not needed, but I find it cleaner to add it
    path.addLine(to: point) //Not needed, but I find it cleaner to add it
    path.close()
    

    Side note, I factorize a little your loop, since you are doing repetitive command inside the if/else, I put them outside.