2011-05-31 3 views
2

J'essaie de créer des applications iOS tout en apprenant et j'ai du mal à comprendre la bonne façon de procéder.Comment mettre à jour mon UIView personnalisé avec drawRect?

Ce que j'ai actuellement est une vue qui est une sous-classe de UIView. C'est clair et je veux l'utiliser comme surface de dessin. Il va s'asseoir sur quelque chose d'autre, comme du papier calque.

L'utilisateur devrait être capable de cliquer sur un point puis sur un autre point et une ligne devrait tracer entre les 2 points. Je reçois les données tactiles, j'ai les points, et je suis capable de dessiner des choses à l'intérieur de drawRect: initialement.

Le problème est que je ne suis pas sûr de savoir comment mettre à jour les choses plus tard. Quand tout se charge et drawRect: est calle, il va tracer une ligne très bien. Mais comment puis-je attirer de nouvelles choses ou modifier des choses déjà dessinées en fonction de ce que fait l'utilisateur. Je sais que je dois appeler setNeedsDisplay, mais pas comment obtenir les données à la vue pour dessiner des choses. J'ai lu un tas de tutoriels/exemples et ils s'arrêtent tous à "Override drawRect: et dessine quelques trucs ... fait!". Comment puis-je transmettre des données à la vue pour le dire «hé, redessinez ce truc et ajoutez cette nouvelle ligne». Ou est-ce que je vais à ce sujet dans le mauvais sens?

EDIT: Je vais essayer d'expliquer mieux la configuration que j'ai.

J'ai un VC. Dans la vue de ce VC j'ai une barre d'outils en bas. Le reste de la zone est occupée par 2 vues. L'une est une vue d'image qui contient une image de référence. L'un est la vue personnalisée qui est claire (papier calque) qui se trouve au sommet. Ils cliquent sur un bouton de la barre d'outils qui active un évaluateur gestuel. Ils cliquent sur l'écran, et je rassemble les données de robinet, éteignez le gesturerecognizer et dessinez HOPEFULLY une ligne. Je l'ai tout fonctionne sauf la partie de dessin.

+2

Vous avez dit que vous "avez les points." Comment les stockez-vous? –

+0

CGPoints contenant les positions de coordonnées du début et de l'arrêt pour chaque "ligne". En ce moment, ils sont détenus par le VC. –

Répondre

4

Vous êtes sur la bonne voie. On dirait que vous devez garder une trace des points.

Voici un exemple de code.

LineDrawView.h

#import <UIKit/UIKit.h> 
@interface LineDrawView : UIView 
{ 
    NSMutableArray *lines; 
    CGPoint pointA, pointB; 
    BOOL activeLine; 
} 
@end 

LineDrawView.m

#import "LineDrawView.h" 
@implementation LineDrawView 
- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) 
    { 
     self.backgroundColor = [UIColor blackColor]; 
     lines = [[NSMutableArray alloc] init]; 
    } 
    return self; 
} 
- (void)dealloc 
{ 
    [lines release]; 
    [super dealloc]; 
} 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [super touchesBegan:touches withEvent:event]; 
    CGPoint point = [[touches anyObject] locationInView:self]; 
    if ([lines count] == 0) pointA = point; 
    else pointB = point; 
    activeLine = YES; 
} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [super touchesMoved:touches withEvent:event]; 
    pointB = [[touches anyObject] locationInView:self]; 
    [self setNeedsDisplay]; 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [super touchesEnded:touches withEvent:event]; 
    pointB = [[touches anyObject] locationInView:self]; 
    [lines addObject:[NSArray arrayWithObjects:[NSValue valueWithCGPoint:pointA], [NSValue valueWithCGPoint:pointB], nil]]; 
    pointA = pointB; 
    pointB = CGPointZero; 
    activeLine = NO; 
    [self setNeedsDisplay]; 
} 

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef c = UIGraphicsGetCurrentContext(); 
    CGContextSetLineWidth(c, 2); 
    CGContextSetLineCap(c, kCGLineCapRound); 
    CGContextSetLineJoin(c, kCGLineJoinRound); 
    CGContextSetStrokeColorWithColor(c, [UIColor grayColor].CGColor); 
    for (NSArray *line in lines) 
    { 
     CGPoint points[2] = { [[line objectAtIndex:0] CGPointValue], [[line objectAtIndex:1] CGPointValue] }; 
     CGContextAddLines(c, points, 2); 
    } 
    CGContextStrokePath(c); 
    if (activeLine) 
    { 
     CGContextSetStrokeColorWithColor(c, [UIColor whiteColor].CGColor); 
     CGPoint points2[2] = { pointA, pointB }; 
     CGContextAddLines(c, points2, 2); 
     CGContextStrokePath(c); 
    } 
} 
@end 
+0

J'ai lu sur touchesBegan etc .. et ils semblent ne pas être ce que je veux. J'ai édité ma question pour essayer d'élaborer sur ce que je fais. J'utilise un VC et ce VC allume/éteint un détecteur de mouvement dépendant de ce que fait l'utilisateur. Je recueille très bien les points et je les garde bien. Je ne sais pas comment transmettre ces données à la vue pour faire le dessin. Corrigez-moi si je me trompe, mais votre solution semble dépendre uniquement de l'UIView personnalisé. Je veux que ça fonctionne là où le UIView personnalisé est bête. Et ne dessine que des lignes basées sur les données que je lui passe du VC. Est-ce que j'ai tort avec cette approche? –

+1

Non, vous n'avez pas tort et votre approche devrait fonctionner correctement. Vous devriez pouvoir ignorer les méthodes 'touch' et remplir le tableau' line' directement depuis une classe différente. Peu importe comment les points et les lignes sont remplis tant que vous appelez 'setNeedsDisplay' juste après la mise à jour du tableau. – tidwall

+0

Oh .. Je suis un idiot.J'ai juste besoin de définir certaines des variables de vues personnalisées à partir de l'intérieur du VC, puis appelez setNeedsDisplay n'est-ce pas? –

Questions connexes