Home Creating a container with a slanted edge
Reply: 2

Creating a container with a slanted edge

Wesley Peeters
1#
Wesley Peeters Published in 2017-11-14 18:19:36Z

I have a client who requested the following in his design:

What is the easiest way to create the yellow container, with the slanted edge on the bottom? Can I do it within the interface builder or do I have to do it programatically? I'm trying to do this in swift.

Rob
2#
Rob Reply to 2017-11-14 20:55:10Z

Can I do it within the interface builder or do I have to do it programmatically?

You'll have to do this programmatically: Define the UIBezierPath, using it as the path of a CAShapeLayer and then mask the view's layer using this shape layer.

@IBDesignable
class SlantedView: UIView {

    @IBInspectable var slantHeight: CGFloat = 50 { didSet { updatePath() } }

    private let shapeLayer: CAShapeLayer = {
        let shapeLayer = CAShapeLayer()
        shapeLayer.lineWidth = 0
        shapeLayer.fillColor = UIColor.white.cgColor    // with masks, the color of the shape layer doesn’t matter; it only uses the alpha channel; the color of the view is dictate by its background color
        return shapeLayer
    }()

    override func layoutSubviews() {
        super.layoutSubviews()
        updatePath()
    }

    private func updatePath() {
        let path = UIBezierPath()
        path.move(to: bounds.origin)
        path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
        path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY))
        path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY - slantHeight))
        path.close()
        shapeLayer.path = path.cgPath
        layer.mask = shapeLayer
    }
}

But by making this an @IBDesignable view, you can then render it in IB so you can at least design the UI with a greater sense of what the final product will look like:

FYI, if you do make this designable, they recommend that you create a separate framework target for your designables (so that if you go to IB while working on your main project, the ability to render the designable views isn't impacted by the fact that your main project may not be in a stable, compilable state).

whistler
3#
whistler Reply to 2017-11-14 19:37:32Z

Maybe make a custom view that you can drop down in interface builder? This version has a property you can set in IB that determines the slant fraction so you can size it the way you want:

@IBDesignable class SlantedView: UIView {

    @IBInspectable var slant: Double = 0.8

    override func prepareForInterfaceBuilder() {
        // Called when initialized in IB
        setup()
    }

    override func awakeFromNib() {
        // Called when initialized in actual app
        setup()
    }

    func setup() {
        layer.backgroundColor = UIColor.yellow.cgColor

        recalculateMask()
    }

    func recalculateMask() {
        let shapeLayer = CAShapeLayer()

        let maskPath = CGMutablePath()
        maskPath.move(to: CGPoint(x: 0, y: 0))
        maskPath.addLine(to: CGPoint(x: bounds.width, y: 0))
        maskPath.addLine(to: CGPoint(x: bounds.width, y: bounds.height))
        maskPath.addLine(to: CGPoint(x: 0, y: bounds.height * CGFloat(slant)))

        shapeLayer.path = maskPath
        layer.mask = shapeLayer
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        recalculateMask()
    }
}
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.447144 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO