Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CAGradientLayer send to back

I have a UIViewController where I create a background gradient with

    CAGradientLayer *gradient = [CAGradientLayer layer];
    ...
    gradient.frame = frame;
    self.backGradient = gradient;
    [self.view.layer insertSublayer:gradient atIndex:0];

it works fine, later I have to send the subview _selectionFrame of my view controller to back:
(I often need to send the _selectionFrame to back and to front, for animation and drawing purpose)

self is the viewController:

[self.view sendSubviewToBack:_selectionFrame]; 

However this sends the _selectionFrame behind the gradient. I want it just above the gradient but below every other subview. The problem is that the gradient is not a view, so i cannot use the functions for the gradient.
I would like to call [self.view sendSubviewToBack:gradient];

But this does not work.

like image 315
AlexWien Avatar asked Jun 22 '13 00:06

AlexWien


3 Answers

.layer has a sublayers property which is a simple array. So you can insert at any index you want. If you want your new layer to be at the back, just insert it at 0, like this:

let newLayer = CALayer() // your layer that you want at the back
view.layer.insertSublayer(newLayer, at: 0)
like image 99
Senõr Ganso Avatar answered Sep 24 '22 07:09

Senõr Ganso


Create a view that contains only the gradient

like image 24
Khanh Nguyen Avatar answered Sep 23 '22 07:09

Khanh Nguyen


The simplest solution is not to insert the gradient layer as a sublayer of self.view.layer. Instead, it should be self.view.layer. A UIView subclass has a class method layerClass that lets you say what class its layer should be.

For example, in your UIView subclass you would add this:

override class var layerClass: AnyClass {
    return CAGradientLayer.self
}

And when referencing self.layer within the view, wrap it a guard let or if let to convert the type like such:

guard let layer = self.layer as? CAGradientLayer else { ... }

Or, it could be the layer of some other subview of self.view, again easily arranged by using the same class method layerClass.

Otherwise, you will have to use layer commands, not view commands, to order the sublayers of self.view. That includes its subviews. In other words, if v is a subview of self.view, then v.layer is a sublayer of self.view.layer and you can order it among its sublayers by rearranging the sublayers array.

like image 41
matt Avatar answered Sep 24 '22 07:09

matt