views:

2983

answers:

2

I'm trying to implement some very simple line drawing animation for my iPhone app. I would like to draw a rectangle on my view after a delay. I'm using performSelector to run my drawing method.

-(void) drawRowAndColumn: (id) rowAndColumn
{
    int rc = [rowAndColumn intValue];
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, currentColor.CGColor);
    CGRect rect = CGRectMake(rc * 100, 100, 100, 100);
    CGContextAddRect(context, rect);
    CGContextDrawPath(context, kCGPathFillStroke);

}

Which is then invoked via:

{ 
    // ...
    int col = 10;
    [self performSelector:@selector(drawRowAndColumn:) 
                   withObject: [NSNumber numberWithInt:col]
                   afterDelay:0.2];
 }

But it seems that when the drawRowAndColumn: message is actually sent, it no longer has access to a valid CGContextRef, as I get errors such as:

<Error>: CGContextAddRect: invalid context

If I replace the performSelector with a direct call to drawRowAndColumn, it works fine. So my first idea was to also pass in the CGContextRef via the performSelector, but I can't seem to figure out how to pass multiple arguments at the same time (that's another good question.)

I'm a total newbie to Cocoa/iPhone/Objective-C, so I welcome constructive criticism on all aspects of this code snippet, thanks.

+2  A: 

You can't just draw at any time like that. You need to implement the drawRect: method of UIView and put your drawing code in there. To get drawRect: to fire you need to let Cocoa know that the view needs to be drawn. For that you can call setNeedsDisplay, or setNeedsDisplayInRect:.

Directly translating your attempt this way you'd call setNeedsDisplay using performSelector:withObject:afterDelay - but that's probably not a good way to do animation.

It depends what you're really trying to do - but you could consider, for example, putting your drawing code in drawRect as I suggested, but start the view hidden. You could then call setHidden:NO using performSelector to make it appear after a delay - or you could smoothly animate it in by starting not hidden, but with an alpha of 0, then change alpha to 1 within a UIView animation block (there's lots about this in the docs).

Phil Nash
I knew it was something simple, thanks!
Limbic System
What *is* a good way to do animation then?
Mk12
Using Core Animation, or the higher-level UIView based wrapper for it. That's what the last paragraph in my answer was talking about (the UIView animation block). You start an animation block, set some UIView properties, then commit the animation and the property changes will be animated in (you can control the timing etc).
Phil Nash
A: 

Hi,

I am new to iPhone development.

I also want to draw rectangle on an image, which function will be help full to me? I am displaying image using UIImageView object and addSubView method of window.

Can you tell me how to draw rectangle when image is displayed? Rectangle will be on the part of image.

Vishal N

Please post this a separate question, not as an answer to another question
Ram