views:

430

answers:

1

Hi everyone. I have written a function that draws x number of squares in a random position every 2 seconds. A square cannot be drawn in the same position twice. Once the app has completed a cycle the grid will be filled in. Now, this works fine when the number of squares drawn is <=8, however when this is higher a square is randomly drawn into the same position as a previous square.

Instead of drawing a square into a random position I have tried drawing them from top-bottom and this works perfectly.

I've been debugging this for a couple of days and I believe the problem lies with setNeedsDisplayInRect.

Hope someone can help. Sorry if I have rambled, its getting late and my head is mashed, lol :)

Below is the code....

- (void)drawRect:(CGRect)rect {
int count = [writeSquares count];

CGContextRef context = UIGraphicsGetCurrentContext();

int radius = 4;

for (int i = 0; i <count; i++)
{
    Square *square = [writeSquares objectAtIndex: i];

    CGContextSetLineWidth(context, 1);
    //CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
    CGContextSetFillColorWithColor(context, [square color].CGColor);
    CGContextMoveToPoint(context, CGRectGetMinX([square squareRect]) + radius, CGRectGetMinY([square squareRect]));
    CGContextAddArc(context, CGRectGetMaxX([square squareRect]) - radius, CGRectGetMinY([square squareRect]) + radius, radius, 3 * M_PI / 2, 0, 0);
    CGContextAddArc(context, CGRectGetMaxX([square squareRect]) - radius, CGRectGetMaxY([square squareRect]) - radius, radius, 0, M_PI / 2, 0);
    CGContextAddArc(context, CGRectGetMinX([square squareRect]) + radius, CGRectGetMaxY([square squareRect]) - radius, radius, M_PI / 2, M_PI, 0);
    CGContextAddArc(context, CGRectGetMinX([square squareRect]) + radius, CGRectGetMinY([square squareRect]) + radius, radius, M_PI, 3 * M_PI / 2, 0);  
    CGContextClosePath(context);
    CGContextFillPath(context);

    //NSLog(@"x = %f x = %f", CGRectGetMaxX([square squareRect]), CGRectGetMinX([square squareRect]));
}

//NSLog(@"Count %i", [writeSquares count]);

[writeSquares removeAllObjects];

}

-(void)drawInitializer:(int) counter{

if(extra != 0) {
    [self setNeedsDisplay];
    [grid removeAllObjects];
    [self calculateGrid];
    counter = counter + extra;
    clear = YES;
    extra = 0;
}

for(int i=0; i<counter; i++) {
    int count = [grid count];
    NSLog(@"counter %i", count);
    if(count != 144) {
        srandom(time(NULL));
        int r = random() % [coordinates count];

        Coordinate *coordinate = [coordinates objectAtIndex:r];


        Square *square = [Square new];
        [square setSquareRect: CGRectMake ([coordinate x] * 25, [coordinate y] * 25, 20, 20)];
        [square setColor: [UIColor randomColor]];
        [writeSquares addObject:square];
        [grid addObject:square];
        [square release];

        [self setNeedsDisplayInRect:CGRectMake ([coordinate x] * 25, [coordinate y] * 25, 20, 20)];

        [coordinates removeObjectAtIndex:r];
        [coordinate release];
    }
    else {
        extra++;
    }
}

//[newlock release];

}

A: 

I'm not sure why this ever worked; it seems to me that all of your -setNeedsDisplayInRect: calls will be coalesced into one update. I'm guessing you'd like the appearance of each square 'popping' in, one after another?

If this is the case, you need to give the OS time to cycle its event loop (these calls will only force a screen update after the current event cycle.)

You should move your loop into a separate method, and call it with either a -performSelector:withObject:afterDelay:, or an NSTimer.

Ben Gottlieb
Bloody hell, it was that simple. I've spent hours debugging that, thanks for your wisdom.
Carl