Take the 2-minute tour ×

I'm calling setNeedsDisplayInRect from an NSTimer function every two seconds. This works perfectly, and draws a square in a random position, with a random color. However, in some circumstances I would like to draw a square x number of times in the NSTimer function (using a for loop) - but, after numerous error testing it seems that drawRect is only called once even though I am running setNeedsDisplayInRect x number of times? I would love some help as I've been trying to figure out this problem all day long. Carl.

Edit below is my code...


- (void)drawRect:(CGRect)rect 
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, currentColor.CGColor);
    CGContextSetFillColorWithColor(context, currentColor.CGColor);
    CGContextAddRect(context, redrawRect);
    CGContextDrawPath(context, kCGPathFillStroke);

    int x = (int)arc4random() % [self.xCoordinates count]; 
    int y = (int)arc4random() % [self.yCoordinates count]; 
    self.currentColor = [UIColor randomColor];
    self.redrawRect = CGRectMake ([[self.xCoordinates objectAtIndex:x] intValue],       [[self.yCoordinates objectAtIndex:y] intValue], 25, 25);
    [self setNeedsDisplayInRect:redrawRect];


- (void) handleTimer: (NSTimer *) timer
         [self.squareView drawInitializer];
share|improve this question
-setNeedsDisplay: only marks a view as needing redisplay; it's not actually redrawn until the next pass through the run loop. –  Wevah Jan 7 '10 at 18:36
Wevah's correct. You are calling -setNeedsDisplayInRect: five times within a tight loop, but the redrawing will not occur until you hit the end of the run loop. –  Brad Larson Jan 8 '10 at 0:40
add comment

3 Answers

up vote 1 down vote accepted

You could refactor the code so that you have a simple class that:

  • stores color
  • stores position
  • has a method to generate random positions, colors, ...

You could then create as many instances as you want and push them into a NSMutableArray.
This way you can iterate over that list, and draw each object in your draw routine.
Whenever you add/delete/modify one of your objects, call setNeedsDisplay:

share|improve this answer
thanks, works like a treat :) –  Carl Jan 8 '10 at 20:04
add comment

Do you determine the position of the square inside the drawRect: method? If so, you should change it. You could for example create an NSRect instance variable that gets drawn by the drawRect: method, BUT the actual position of the NSRect is set in another method (e.g. your NSTimer function).

Oh, and you should probably post your code so people can more easily help you out!

share|improve this answer
add comment

you could create a class that has the ability to draw itself, then create as many instances of this class that you need.

share|improve this answer
add comment

Your Answer


