Search code examples
iosswiftxcodeuiviewcalayer

iOS - centralizing CAGradientLayer into parent UIView


I have a bgLayer: CAGradientLayer with bigger dimensions then it's parent view bgView. The layer is being inserted correctly using bgView.layer.insertSublayer, but I can't create the frame of my bgLayer centralized with my smaller bgView.

How could I centralize my bgLayer into my bgView?


Solution

  • I believe this is what you mean...

    Larger Gradient view centered on smaller UIView. First image is with .clipsToBounds = true, second image .false.:

    enter image description hereenter image description here

    Both images use the same view size: 100 x 100 and the same gradient size: 150 x 150. You can paste this code into a Playground page to see how it works.

    import UIKit
    import PlaygroundSupport
    
    let container = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
    
    container.backgroundColor = UIColor(red: 0.3, green: 0.5, blue: 1.0, alpha: 1.0)
    
    PlaygroundPage.current.liveView = container
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // 150 x 150 frame for the gradient layer
            let gFrame = CGRect(x: 0, y: 0, width: 150, height: 150)
    
            // 100 x 100 frame for the View
            let vFrame = CGRect(x: 100, y: 100, width: 100, height: 100)
    
            let v = UIView(frame: vFrame)
            self.view.addSubview(v)
    
            // add a border to the UIView so we can see its frame
            v.layer.borderWidth = 2.0
    
            // set up the Gradient Layer
            let gradient = CAGradientLayer()
            gradient.colors = [UIColor.red.cgColor,UIColor.yellow.cgColor]
            gradient.locations = [0.0, 1.0]
            gradient.startPoint = CGPoint(x: 0.0, y: 0.0)
            gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
    
            // set the initial size of the gradient frame
            gradient.frame = gFrame
    
            // center the gradient frame over (or inside, if smaller) the view frame
            gradient.frame.origin.x = (v.frame.size.width - gradient.frame.size.width) / 2
            gradient.frame.origin.y = (v.frame.size.height - gradient.frame.size.height) / 2
    
            // add the gradient layer to the view
            v.layer.insertSublayer(gradient, at: 0)
    
            // set to true to clip the gradient layer
            // set to false to allow the gradient layer to extend beyond the view
            v.clipsToBounds = true
    
        }
    
    }
    
    let vc = ViewController()
    container.addSubview(vc.view)