2010-04-06 8 views
3

Je suis encore un peu à l'aise dans la programmation CoreGraphics, alors s'il vous plaît, gardez-moi de l'être. J'essaie d'écrire une application, ce qui permet à l'utilisateur de frotter une image avec le doigt. J'ai la fonctionnalité de base clouée, mais le résultat est léthargique puisque l'écran est complètement redessiné chaque fois qu'un toucher est rendu. J'ai fait quelques recherches et j'ai découvert que je ne peux actualiser qu'une partie de l'écran en utilisant la méthode setNeedsDisplayInRect: de UIView.setNeedsDisplayInRect: peint un rectangle blanc seulement

Cela appelle drawRect: comme prévu, mais tout ce que je dessine dans le drawRect: après le setNeedsDisplayInRect: est ignoré. Au lieu de cela, la zone du paramètre rect est simplement remplie de blanc. Peu importe ce que je dessine à l'intérieur, tout ce que je finis avec est un rectangle blanc.

Essentiellement, ce que je fais:

1) lorsque l'utilisateur touche l'écran, cette touche est rendue dans un masque 2) lorsque le drawRect: est appelée, l'image est masquée avec ce masque

Il doit y avoir quelque chose de simple que je néglige, sûrement?

Répondre

2

J'ai trouvé une solution, mais il m'échappe encore comment exactement cela fonctionne. Voici le code:

Cette méthode retourne le rectangle donné de la même manière, dans laquelle la transformation de coordonnées dans le contexte flips le système de coordonnées contexte:

- (CGRect) flippedRect:(CGRect)rect 
{ 
    CGRect flippedRect = rect; 

    flippedRect.origin.y = self.bounds.size.height - rect.origin.y - rect.size.height; 

    return CGRectIntersection(self.bounds, flippedRect); 
} 

Calcule le rectangle à être mis à jour à partir de la touche emplacement. Notez que le rectangle se renversé:

- (CGRect) updateRectFromTouch:(UITouch *)touch 
{ 
    CGPoint location = [touch locationInView:self]; 

    int d = RubbingSize; 

    CGRect touchRect = [self flippedRect:CGRectMake(location.x - d, location.y - d, 2*d, 2*d)]; 

    return CGRectIntersection(self.frame, touchRect); 
} 

En render toucher les « rectangles » basculées de mise à jour sont sous la contrainte:

- (void) renderTouch:(UITouch *)touch 
{ 
    // 
    // Code to render into the mask here 
    // 

    if (m_updateRect.size.width == 0) 
    { 
     m_updateRect = [self updateRectFromTouch:touch]; 
    } 
    else 
    { 
     m_updateRect = CGRectUnion(m_updateRect, [self updateRectFromTouch:touch]); 
    } 
} 

La vue entière est actualisée avec environ 20Hz au cours du processus de Fingerpainting. La méthode suivante est appelée à chaque 1/20ème seconde et soumet le rectangle pour le rendu:

- (void) refreshScreen 
{ 
    if (m_updateRect.size.width > 0) 
    { 
     [self setNeedsDisplayInRect:[self flippedRect:m_updateRect]]; 
    } 
} 

Voici une méthode d'aide à comparer aux rectangles:

BOOL rectIsEqualTo(CGRect a, CGRect b) 
{ 
    return a.origin.x == b.origin.x && a.origin.y == b.origin.y && a.size.width == b.size.width && a.size.height == b.size.height; 
} 

Dans la drawRect: méthode, le rectangle de mise à jour est utilisé pour dessiner uniquement la partie à mettre à jour.

- (void)drawRect:(CGRect)rect 
{ 
    BOOL drawFullScreen = rectIsEqualTo(rect, self.frame); 

    // Drawing code 

    CGContextRef context = UIGraphicsGetCurrentContext(); 

    // Turn coordinate system around 

    CGContextTranslateCTM(context, 0.0, self.frame.size.height); 

    CGContextScaleCTM(context, 1.0, -1.0); 

    if (drawFullScreen) 
    { 
     // draw the full thing 
     CGContextDrawImage(context, self.frame, self.image); 
    } 
    else 
    {  
     CGImageRef partialImage = CGImageCreateWithImageInRect(self.image, [self flippedRect:m_updateRect]); 

     CGContextDrawImage(context, m_updateRect, partialPhoto); 

     CGImageRelease(partialImage); 
    } 

     ... 

    // Reset update box 

    m_updateRect = CGRectZero; 
} 

Si quelqu'un peut m'expliquer pourquoi le retournement fonctionne, j'apprécierais.

1

Le problème de retournement est probablement dû au fait que UIKit a une coordonnée «retournée» par rapport à Core Graphics.

Documentation Apple here

Questions connexes