Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Masking a CALayer - iPhone

I'm creating a custom on / off toggle switch for the iPhone (similar to the standard switch) and i'm at the point where I'm setting the mask of the slider, but calling [[myView layer] setMask:maskLayer] sets the position of the mask layer relative to the layer it's masking, not relative to the container layer of the mask layer. For this particular scenario, the position of the mask layer needs to be set relative to it's containing layer because the toggle slider will move underneath the mask and the mask should stay stationary.

Without having to animate the mask AND the toggle slider component to achieve the desired effect, anyone know how to make this work? Here's what I've got so far:

CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
CGMutablePathRef path = CGPathCreateMutable();

CGPathAddEllipseInRect(path, nil, CGRectMake(0, 0, 13, 13));
CGPathAddEllipseInRect(path, nil, CGRectMake(30, 0, 13, 13));
CGPathAddRect(path, nil, CGRectMake(6, 0, 32, 13));

[maskLayer setPath:path];
[maskLayer setFillColor:[[UIColor greenColor] CGColor]];

[[self layer] addSublayer:maskLayer];

[maskLayer setPosition:CGPointMake(2, 2)];

[self addSubview:toggleView];

[[toggleView layer] setMask:maskLayer];
like image 586
jtrim Avatar asked Feb 15 '10 17:02

jtrim


1 Answers

A mask is just a special kind of sublayer, so the superlayer of the mask will always be the layer it's masking. There is no way around it. Also, you are violating this warning in the documentation:

When setting the mask to a new layer, the new layer’s superlayer must first be set to nil, otherwise the behavior is undefined.

You should remove the [[self layer] addSublayer:maskLayer]; line.

To solve your problem, I would create another layer or view that contains everything that is now on your toggleView and then add that layer to your toggleLayer as a sublayer. That way, you can position the new sublayer independently of the mask and if you move the parent layer, both the mask and the sublayer will move together (which is what they should do if I understand you correctly).

like image 94
Ole Begemann Avatar answered Oct 13 '22 22:10

Ole Begemann