我有一个继承自UIControl的类来处理touchEvents,我不明白为什么'setNeedsDisplay'方法需要在touchEvents上调用两次才能在UI中绘制正确的状态。我在一些示例中看到了这种模式,其中各种触摸[Began | Ended]方法都直接调用setNeedsDisplay,然后使用performSelector再次调用延迟。
我可以看到未调用第二个setNeedsDisplay时的结果 - 控件首先呈现在选定状态但未恢复到正常状态,因此背景保持为选中状态。
为什么会出现这种情况?
// a class that inherits from UIControl
- (void)drawRect:(CGRect)rect
{
NSLog(@"drawRect, control state: %d", self.state);
if (self.state == UIControlStateNormal)
{
[self setContentToNormalState];
[self setBackgroundColor:[UIColor whiteColor]];
NSLog(@"Set background color: White");
}
else
{
[self setContentToSelectedState];
[self setBackgroundColor:[UIColor lightGrayColor]];
NSLog(@"Set background color: Grey");
}
[super drawRect:rect];
}
- (void)hesitateUpdate
{
[self setNeedsDisplay];
}
#pragma mark - Touch event handling
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self setHighlighted:YES];
[self setNeedsDisplay];
[super touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self setHighlighted:NO];
[super touchesMoved:touches withEvent:event];
// [self setNeedsDisplay];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesCancelled:touches withEvent:event];
[self setHighlighted:NO];
[self setNeedsDisplay];
[self performSelector:@selector(hesitateUpdate) withObject:nil afterDelay:0.1];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
[self setHighlighted:NO];
[self setNeedsDisplay];
// Even with the following, if I tap and hold momentarily in the simulator,
// sometimes, the control has the gray background instead of white at the end
[self performSelector:@selector(hesitateUpdate) withObject:nil afterDelay:0.1];
}