Question

I wrote a little custom-view-application using cocoa. And later (yes, i know it's bad) I just asked myself: Would this work for cocoa touch as well? Of course id did not work instantly, I had to change the class names and so on. Well, i refreshed the View, whenever it was needed, using a NSTimer and the setNeedsDisplay: method. Worked pretty well under cocoa, but absolutely not under cocoa touch.

I can't explain it to myself an I actually don't know what lines of code could help someone to solve the problem. Maybe here is the Timer:

[self setMyTimer: [NSTimer scheduledTimerWithTimeInterval:0.03 target:self selector:@selector(myTarget:) userInfo:nil repeats:YES]];

And it's target:

- (void) myTarget:(NSTimer *)timer {
    [self setNeedsDisplay];
}

The timer is invoked every 30 ms, I checked that with an NSLog.

In the drawRect: method I did actually just draw some shapes and did nothing else. Just in case it would be necessary to call some kind of clearRect: method. As I said, under cocoa it worked.

Was it helpful?

Solution

I would first verify whether drawRect: is running by using a breakpoint or log statement.

Then, make sure that your view is actually on the screen. What is the value of [self superview]? You should also do something like self.backgroundColor = [UIColor redColor]; so that you can see where your view is.

Just because you're marking the view dirty every 30ms doesn't mean it will draw every 30ms. It generally should (that's about 30fps), but there isn't a guarantee. drawRect: shouldn't rely on how often it's called. From your question, I assume you mean that it's never drawing, rather than just not drawing as often as expected.

OTHER TIPS

Here's the discussion about setNeedsDisplay (note the LACK of arguments) from the documentation of UIView:

You can use this method to notify the system that your view’s contents need to be redrawn. This method makes a note of the request and returns control back to your code immediately. The view is not actually redrawn until the next drawing cycle, at which point all invalidated views are updated.

You should use this method to request that a view be redrawn only when the content or appearance of the view change. If you simply change the geometry of the view, the view is typically not redrawn. Instead, its existing content is adjusted based on the value in the view’s contentMode property. Redisplaying the existing content improves performance by avoiding the need to redraw content that has not changed.

In contrast, here's the discussion about setNeedsDisplay: (note the argument) from the documentation of NSView:

Whenever the data or state used for drawing a view object changes, the view should be sent a setNeedsDisplay: message. NSView objects marked as needing display are automatically redisplayed on each pass through the application’s event loop. (View objects that need to redisplay before the event loop comes around can of course immediately be sent the appropriate display... method.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top