La máscara CALayer no funciona correctamente

Estoy intentando enmascarar una UIView a una image usando su propiedad de máscara de capa. He visto innumerables ejemplos que dicen "es tan fácil". Sin embargo, después de un poco de ajustes, no puedo reproducir los resultados descritos. Configurar la máscara de capa solo hace que la vista desaparezca. Aquí está el código que estoy usando:

- (void)setMaskImage:(UIImage *)maskImage { _maskImage = maskImage; self.layer.mask.contents = (__bridge id)(_maskImage.CGImage); } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self != nil) { self.layer.mask = [CALayer layer]; } return self; } - (void)setFrame:(CGRect)frame { [super setFrame:frame]; self.layer.mask.frame = self.layer.bounds; } 

Y aquí está la image que estoy tratando de usar para enmascarar la vista: http://cl.ly/0a300G2r133V

Una posibilidad es que el sistema no use realmente setFrame: para configurar la geometry de su vista. Puede usar setCenter: y setBounds: Otra posibilidad es que el sistema no configure la geometry de su vista en absoluto, y solo se establece una vez, en la [super initWithFrame:frame] , antes de agregar la capa de máscara.

De todos modos, en lugar de anular setFrame: debes anular layoutSubviews :

 - (void)layoutSubviews { [super layoutSubviews]; self.layer.mask.frame = self.bounds; } 

Puede anular el método UIView drawRect () para su apariencia personalizada en la pantalla. Intente utilizar el siguiente enfoque.

 //code for drawRect() CGContextRef context = UIGraphicsGetCurrentContext(); CGContextAddRect(context,ImageFrame); CGContextClip(context); CGContextClearRect(context,ImageFrame); [super drawRect:rect]; 

Hará que su vista sea transparente en su área imageFrame.

El siguiente funciona como se esperaba:

 - (void)setMaskImage:(UIImage *)maskImage { if (_maskView == nil) { _maskView = [[UIImageView alloc] initWithImage:maskImage]; _maskView.frame = self.bounds; self.layer.mask = _maskView.layer; } else { _maskView.image = maskImage; } } - (UIImage *)maskImage { return _maskView.image; } - (void)setBounds:(CGRect)bounds { [super setBounds:bounds]; _maskView.frame = self.bounds; } 

No estoy seguro de por qué simplemente usar una llanta CALayer no funcionaba, pero esto agrega la ventaja de trabajar bien con imágenes estirables.