This is surprisingly easy. The solution is to move the UIButton’s layer to be a sublayer of the CALayer that you want. There are a couple of things to watch out for. I’d assume that the buttons layer must be a descendant of the layer of the UIView that you orignially add the button to.
A larger problem is caused by the way that UIViews manage their
subviews. When you call the
addSubview: method the layer of
your button is added as a sublayer of the view. The ‘subviews’
array isn’t updated. This is because the subviews array doesn’t
exist until it is needed. Instead I believe that it is generated
and cached from the sublayers of the views layer.
Here is the view immediately after adding a subview with
If I now call
subviews on the view it looks like this:
If I now do
[myView addSubview:(UIView *)[[UIView alloc] initWithFrame:CGRectMake (0.0, 0.0, 128, 128)]]
the view goes back to looking as it did originally
_subviewCache = nil).
The problem with this is that the view uses the
work out where its lowest descendant view is, so if your view
_subviewCache then the button won’t work.
If you know that you aren’t going to add any more subviews to your view then you can do something like this:
If anything now causes the
_subviewCache to be regenerated then this will
break your buttons.
A better approach may be to subclass the view which you want to add movable layers to like this:
Then make sure that the
movableLayerViews array contains all
the views where you want to be able to add their layer to a
different layer, and it should all work.
You can find my test project for this here.