1
votes

I have a UIView-derived view that is drawn only once and never updated.

Calling [self setNeedsDisplay] has no effect. What could cause this?

It doesn't matter whether the drawing code is in

  • drawRect:, or
  • drawLayer:inContext: (with an empty drawRect() defined)

If drawLayer:inContext is not defined, then drawRect is called. But just once (during layout).

- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx {
  // drawing occurs, but just once (during view layout)
}

`- (void)drawRect:(CGRect) rect {
  // empty -- never called
}

A small list of what I've tried:

  • [self setNeedsDisplay]
  • [self.layer setNeedsDisplay]
  • [self.mySubLayer setNeedsDisplay]
  • self.contentMode = UIViewContentModeRedraw;
  • creating the view manually, instead of loading it from a .nib (no effect)
  • Removing the use of layers (and sublayers) and using just drawRect (no effect)
1
Are you sure that setNeedsDisplay gets called? Show that code, set a breakpoint where you expect it to happen, and report back...Cubs Fan Ron
To follow up on Cubs's comment, are you sure you are calling UIKit methods on the main thread? That can have some wacky consequences like nothing happening if you do not.D.C.
Yes, I've set breakpoints. Good point. Absolutely certain. Spent several hours on this, reading all posts I can find and double-checking everything. Even the instance is the same as the one that got initialized by the nib and pushed into the IBOutput (address does not change). There are lots of variables, so I converted everything not to use CALayer, but that made no difference, so I'm putting it back. It's something strange about the iOS framework...StuWeldon
@darren: That was it! I was calling setNeedsDisplay from a callback from a non-UI thread. If you add this as an answer, I'll mark it as the answer. What a bizarre requirement! Most UI frameworks don't allow drawing from non-UI threads, but you can at least notify them that they should draw. Instead, the framework just decides to ignore the request?StuWeldon
Cool, glad that worked. That same problem has bitten me several times when I'm careless. To be honest I'd prefer the program just crash rather than do nothing.D.C.

1 Answers

5
votes

So this can be marked as answered: be sure to call UIKit methods on the main thread.