问题
I'm trying to use setNeedsDisplayInRect:
in iOS5 to optimize some drawing code. The setup is simple: I have an array of CGRect 'hotspots' that function as buttons. When a touch is detected I find the CGRect it occurred in and call setNeedsDisplayInRect:
on the view with that rect as a param. All the CGRects are valid for the view - it uses them to do it's initial drawing and that comes out correctly.
What I am seeing (as the Console dump below shows) is that the first call to setNeedsDisplayInRect:
passes the view frame as rect, not the rect I specified. Subsequent calls are correct.
Can anyone confirm this as a bug or see that I am doing something incorrectly here? All the code is below. -- Thanks!
WRONG -> drawRect with rect 0.000000 0.000000 70.000000 660.000000
drawRect with rect 15.000000 260.000000 40.000000 40.000000
drawRect with rect 15.000000 310.000000 40.000000 40.000000
drawRect with rect 15.000000 360.000000 40.000000 40.000000
drawRect with rect 15.000000 410.000000 40.000000 40.000000
drawRect with rect 15.000000 460.000000 40.000000 40.000000
drawRect with rect 15.000000 510.000000 40.000000 40.000000
drawRect with rect 15.000000 410.000000 40.000000 40.000000
drawRect with rect 15.000000 310.000000 40.000000 40.000000
drawRect with rect 15.000000 260.000000 40.000000 40.000000
drawRect with rect 15.000000 110.000000 40.000000 40.000000
drawRect with rect 15.000000 610.000000 40.000000 40.000000
drawRect with rect 15.000000 510.000000 40.000000 40.000000
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self.view];
CGRect rect;
int cnt = self.barNoteArray.count;
for (int i = 0; i < cnt; i++) {
rect = [[self.barNoteArray objectAtIndex:i] cellRect];
if (CGRectContainsPoint(rect, point)) {
self.bar.highlightIndex = 1;
[self.bar setNeedsDisplayInRect:rect];
break;
}
}
}
- (void)drawRect:(CGRect)rect
{
if (highlightIndex){
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor greenColor].CGColor);
CGContextAddRect(context, rect);
CGContextFillPath(context);
highlightIndex = 0;
printf("drawRect with rect %f %f %f %f \n", rect.origin.x,
rect.origin.y,
rect.size.width,
rect.size.height);
} else {
// other drawing code
}
回答1:
I am having this problem as well. I have narrowed it down to the following situation:
It seems that this is happening when I shift from one UIView to a second one. In my case, the user it selecting a painting tool in one UIView, then drawing on a underlaying UIView (the canvas).
It seems the initial stroke changes the rect received in drawRect from what you put in there to the full view size. Once those one or two drawRects have been drawn, it does not change what you put in there.
I can prove that it is a setNeedsDisplayInRect because if I comment the offending line out drawRect no longer is called. The rect just before the call shows then proper sub rectangle to update, the rect in drawRect shows a different rectangle.
Again, this is only happening on the initial move from one UIView to another (it seems).
来源:https://stackoverflow.com/questions/9299018/setneedsdisplayinrect-bug-in-ios5