Create a Diagonal Custom UIView in Swift

后端 未结 2 1613
广开言路
广开言路 2020-12-29 17:44

I am working on designing custom UIimageview in swift. I want to create a UIimageview using beizerpath similar to this

The coding should be in swift. Any help is

相关标签:
2条回答
  • 2020-12-29 17:50

    I'm using something like this and it worked fine, you can add any thing you want to the view

    import UIKit
    
    class CustomView: UIView {
    
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
        // Get Height and Width
        let layerHeight = layer.frame.height
        let layerWidth = layer.frame.width
        // Create Path
        let bezierPath = UIBezierPath()
        //  Points
        let pointA = CGPoint(x: 0, y: 0)
        let pointB = CGPoint(x: layerWidth, y: 0)
        let pointC = CGPoint(x: layerWidth, y: layerHeight)
        let pointD = CGPoint(x: 0, y: layerHeight*2/3)
        // Draw the path
        bezierPath.move(to: pointA)
        bezierPath.addLine(to: pointB)
        bezierPath.addLine(to: pointC)
        bezierPath.addLine(to: pointD)
        bezierPath.close()
        // Mask to Path
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = bezierPath.cgPath
        layer.mask = shapeLayer
    }
    }
    
    0 讨论(0)
  • 2020-12-29 17:53

    Create a CAShapeLayer and supply it a path and a fillColor:

    @IBDesignable
    public class AngleView: UIView {
    
        @IBInspectable public var fillColor: UIColor = .blue { didSet { setNeedsLayout() } }
    
        var points: [CGPoint] = [
            .zero,
            CGPoint(x: 1, y: 0),
            CGPoint(x: 1, y: 1),
            CGPoint(x: 0, y: 0.5)
        ] { didSet { setNeedsLayout() } }
    
        private lazy var shapeLayer: CAShapeLayer = {
            let _shapeLayer = CAShapeLayer()
            self.layer.insertSublayer(_shapeLayer, at: 0)
            return _shapeLayer
        }()
    
        override public func layoutSubviews() {
            shapeLayer.fillColor = fillColor.cgColor
    
            guard points.count > 2 else {
                shapeLayer.path = nil
                return
            }
    
            let path = UIBezierPath()
    
            path.move(to: convert(relativePoint: points[0]))
            for point in points.dropFirst() {
                path.addLine(to: convert(relativePoint: point))
            }
            path.close()
    
            shapeLayer.path = path.cgPath
        }
    
        private func convert(relativePoint point: CGPoint) -> CGPoint {
            return CGPoint(x: point.x * bounds.width + bounds.origin.x, y: point.y * bounds.height + bounds.origin.y)
        }
    }
    

    Now, I made this designable (so if you put it in a separate framework target, you can add this view right in your storyboard and see it rendered there). It still works if you're not using storyboards. It just can be convenient to do so:

    I also used relative coordinates (with values ranging from zero to one) and have a method to convert those to actual coordinates, but you can hard code your coordinates if you want. But using this as values from zero to one, you have an angular view that can participate in auto-layout without needing to worry about changing specific coordinate values.

    Finally, minor things that might seem trivial, but I construct the path in layoutSubviews: That way, as the view changes size (whether via auto-layout or programmatic changes), the view will be correctly re-rendered. Likewise, by using didSet for fillColor and points, if you change either of those, the view will be re-rendered for you.

    Feel free to change this as you see fit, but hopefully this illustrates the basic idea of just having a CAShapeLayer with a custom path.


    If you use insertSublayer, you can then combine this with other subviews of the AngleView, e.g.:

    0 讨论(0)
提交回复
热议问题