I have the following set-up of CAShapeLayers and UIViews attached to a UIView:
[self.layer addSublayer:self.shapeLayer1];
if (someCase)
{
[self.layer addSublayer:self.shapeLayerOptional];
}
[self.layer addSublayer:self.shapeLayer2];
[self addSubview: self.view1];
I want there to be functionality that allows the user to insert another UIView, let's call it view0, before shapeLayer2, but I don't know how to accomplish this. The parent UIView subviews property only includes view1, while its layer.sublayers property includes the layers of the shapelayers and subview1, but I don't want to insert subview0.layer into layers.sublayers because subview0 has a UITouchGestureRecognizer. This seems like a simple design problem on the surface but it's really confusing me for some reason. Anyone have any recommended solutions? I want to try and avoid wrapping the CAShapeLayers into UIViews if I can.
Couple things to note...
Layers - whether
CALayer,CAShapeLayer,CAGradientLayer, etc - belong to a view. You can manipulate the appearance of the layers via the.zPosition.Also, a layer doesn't really exist on its own... it must be added as a sublayer to a view's layer.
A view has its own layer ... so when trying to manipulate layer ordering, that must be taken into account.
So, your goal is to have one view with multiple layers, another view with one or more layers, and insert the second view (and its layers) between layers of the first view.
If we start with two views -- yellow with two
CAShapeLayersublayers; cyan with oneCAShapeLayersublayer:Looks like this (with the layers separated out):
and we want to insert cyanView (and its triangle sublayer) between the rectangle and oval layers of yellowView:
Let's add cyanView as a subview of yellowView, offset by 40,40 and
yellowView.clipsToBounds = trueso we can see it's a subview:That gives us what we expect... but not what we want, because the rect and oval layers belong to yellowView.
To move the oval layer to the top, we'll change the
.zPositionproperties:and we get this result:
cyanView and its triangle layer are now between yellow view's rectangle and oval layers.
Goal accomplished? Maybe...
Let's look at the Debug View Hierarchy now:
Notice that the layers are not separated from their views.
In the first Hierarchy images above, I used individual views just to show what we're trying to do.
Now, managing the
.zPositionvalues may work for you... but I would think it would be much easier to implement either only layers, or only views (we can change a view's layer class to eliminate the need to add a sublayer to every view).Here is some example code to produce the above:
ViewsAndLayersViewController.h
ViewsAndLayersViewController.m