2010-06-09 11 views
1

Je souhaite créer un effet de masquage sur un UIView afin de réaliser ce qui suit. Je vais afficher une boîte scellée dans l'écran et l'utilisateur sera en mesure de toucher (gratter) l'écran afin de révéler ce qui se cache derrière cette image (UIView). Quelque chose de semblable à ces billets de loterie où vous suppose de gratter un matériau de couverture qui est au-dessus des résultats ..Création d'un effet de masquage sur une vue

Si quelqu'un pourrait me diriger dans la bonne direction serait génial, je ne sais pas comment commencer à le faire. ..

grâce

Répondre

2

édition de pixels se fait généralement avec un CGBitmapContext. Dans ce cas, je pense que vous voudrez créer un bitmap en niveaux de gris qui représente juste le canal alpha de la zone de travail. Au fur et à mesure que l'utilisateur gratte, vous allez peindre dans ce bitmap.

Pour utiliser un GCBitmapContext comme masque pour une image, vous devez d'abord créer une image de masquage à partir de l'image bitmap. Utilisez CGImageMaskCreate et passez dans un fournisseur de données qui pointe vers les mêmes pixels utilisés pour créer l'image bitmap. Ensuite, utilisez CGImageCreateWithMask avec votre image à gratter et l'image du masque qui est le bitmap.

Vous ne pouvez pas dessiner directement dans l'iPhone. Chaque fois que l'utilisateur déplace un doigt, vous devez modifier le bitmap du masque puis invalider l'UIView qui dessine l'image. Il se peut que vous soyez à nouveau capable de dessiner la même image, ou que vous ayez besoin de reconstruire le masque et l'image masquée chaque fois que vous dessinez. Tant que l'image du masque se réfère directement aux données de pixels bitmap, très peu de mémoire est réellement allouée.

Donc psuedocode vous voulez quelque chose comme ceci:

scratchableImage = ... 
width = CGImageGetWidth(scratchableImage); 
height = CGImageGetHeight(scratchableImage); 
colorspace = CGColorSpaceCreateDeviceGray(); 
pixels = CFDataCreateMutable(NULL , width * height); 
bitmap = CFBitmapContextCreate(CFDataGetMutableBytePtr(pixels) , width , height , 8 , width , colorspace , kCGImageAlphaNone); 
provider = CGDataProviderCreateWithCFData(pixels); 
mask = CGImageMaskCreate(width , height , 8 , 8 , width , provider , NULL , false , kCGRenderingIntentDefault); 
scratched = CGImageCreateWithImageInRect(scratchableImage , mask); 

À ce stade, scratched aura un canal alpha dictée par bitmap mais bitmap a des données d'ordures. Le bit pixels blanc est opaque et les pixels noirs sont clairs. Peignez tous les pixels blancs en bitmap puis, lorsque l'utilisateur gratte, peignez des pixels noirs. Je pense que les modifications apportées à bitmap s'appliqueront automatiquement chaque fois que scratched sera dessinée, mais si ce n'est pas le cas, recréez simplement mask et scratched chaque fois que vous dessinez.

Vous avez probablement un UIView personnalisé pour le suivi des entrées utilisateur. Vous pouvez obtenir votre vue personnalisée UIImageView et laissez dessiner l'image ou procédez comme suit:

-(void) drawRect:(CGRect)inDirty { 
    // assume scratched is a member 
    CGContextDrawImage(UIGraphicsGetCurrentContext() , [self bounds] , scratched); 
} 

Alternativement, vous pouvez sauter créer scratched et utiliser à la place CGContextClipToMask et d'en tirer le scratchableImage d'origine directement. S'il n'y a pas scratchableImage et que votre zone de travail est une hiérarchie de texture ou de vue, adoptez cette approche.