views:

905

answers:

3

Implemented my own drawRect method and I'm trying to redraw the shape from a Controller class and I can't figure out how to correctly implement setNeedsDisplay to redraw the UIView. Please help!!

I know the code is ugly, but here is the custom method:

- (void)drawRect:(CGRect)rect{
// Drawing code
NSArray *kyle = [self pointsForPolygonInRect:rect numberOfSides:[pshape numberOfSides]];
CGContextRef c = UIGraphicsGetCurrentContext();

int counter = [kyle count];
NSLog(@"counter: %d",counter);
int i = 0;
BOOL first = YES;

NSValue *kylevalue;
CGPoint thePoint;
for (i = 0; i < counter; i++) {
 kylevalue = [kyle objectAtIndex:i];
 thePoint = [kylevalue CGPointValue];
 if (first) { //start.
  CGContextMoveToPoint(c, thePoint.x, thePoint.y+5.0);
  first = NO;
 } else { //do the rest
  CGContextAddLineToPoint(c,  thePoint.x, thePoint.y+5.0);
 }
}
CGContextClosePath(c); //solid color
CGContextDrawPath(c, kCGPathFillStroke);

}

+1  A: 

I'm not sure I understand your question. Calling -setNeedsDisplay on a view causes it to be redrawn via its -drawRect: method.

titaniumdecoy
Sorry for the confusion. I'm trying to refresh the view from another class and when I call: [pview setNeedsDisplay]; Nothing happens. It doesn't error when I run it, but it doesn't respond either. I put an NSLog message to display when it enters drawRect and it only enters once when the application launches.
You should check that pview is not nil, since messages sent to nil are silently ignored.
titaniumdecoy
A: 

just a few thoughts 1. have you verified that your method is getting called? 2. have you verified that your array of points is in fact populated with more than one point? 3. are the points actually in the viewable area of the frame? 4. I don't see you setting the stroke line width, color or fill colors.

A: 

I've had similar problems with redrawing not working as I expected either. It seems as though setNeedsDisplay does not force children to redraw, for those you need to call their setNeedsDisplay method.

For my needs I wrote a category to redraw the entire screen by calling setNeedsDisplay on every single view. This can of course easily be modified to start from a specific view as opposed to all windows.

@implementation UIApplication (Extensions)

+ (void) redrawScreen {
 NSMutableSet* todo = [NSMutableSet set];
 NSMutableSet* done = [NSMutableSet set];
 [todo addObjectsFromArray:[[UIApplication sharedApplication] windows]];

 while ([todo count] > 0) {
  UIView* view = [todo anyObject];
  [view setNeedsDisplay];

  [done addObject:view];
  [todo removeObject:view];

  if (view.subviews) {
   NSMutableSet* subviews = [NSMutableSet setWithArray:view.subviews];

   [subviews minusSet:done];
   [todo unionSet:subviews];
  }
 }
}

@end

Hope this is of help to someone

mattmook