QuartzCore在清除UIView上的表现

时间:2011-01-16 14:11:23

标签: objective-c ipad quartz-graphics

我有一个UIView,我在init方法中将背景颜色设置为clear。然后我在drawRect中的2个点之间绘制一条蓝线。第一点是视图的第一次触摸,第二点是在调用touchesMoved时更改。

使线的一端固定,另一端与用户手指一起移动。然而,当背景颜色清晰时,该线具有相当大的延迟并且跳过(不平滑)。

如果我将背景颜色更改为黑色(只是取消注释setbackgroundcolor线),那么移动会更加平滑,看起来很棒,除了你无法看到背后的视图。

我该如何解决这个问题? (在iPad上,我只有模拟器,并且目前无法访问设备)因此性能平稳,但背景清晰,因此您可以看到背景视图。

-(id) initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        //self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

-(void) drawRect:(CGRect)rect {
if (!CGPointEqualToPoint(touchPoint, CGPointZero)) {
    if (touchEnded) {
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextClearRect(context, rect);
    } else {

CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, rect);
    CGContextSetLineWidth(context, 3.0f);
    CGFloat blue[4] = {0.0f, 0.659f, 1.0f, 1.0f};
    CGContextSetAllowsAntialiasing(context, YES);
    CGContextSetStrokeColor(context, blue);
    CGContextMoveToPoint(context, startPoint.x, startPoint.y);
    CGContextAddLineToPoint(context, touchPoint.x, touchPoint.y);
    CGContextStrokePath(context);

    CGContextSetFillColor(context, blue);

    CGContextFillEllipseInRect(context, CGRectMakeForSizeAroundCenter(CGSizeMake(10, 10), touchPoint));
    CGContextFillEllipseInRect(context, CGRectMakeForSizeAroundCenter(CGSizeMake(10, 10), startPoint));
    }   
    }
}



-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    self.touchEnded = NO;
    if ([[touches allObjects] count] > 0) 
        startPoint = [[[touches allObjects] objectAtIndex:0] locationInView:self];
        touchPoint = [[[touches allObjects] objectAtIndex:0] locationInView:self];
    [self setNeedsDisplay];
}

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    self.touchEnded = NO;
    if ([[touches allObjects] count] > 0) 
        touchPoint = [[[touches allObjects] objectAtIndex:0] locationInView:self];
    [self setNeedsDisplay];
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    self.touchEnded = YES;
    [self setNeedsDisplay];
    [self removeFromSuperview];
}
- (void)dealloc {
    [super dealloc];
}

1 个答案:

答案 0 :(得分:1)

首先,您应该在设备上测试性能,而不是在模拟器中测试性能。大多数与图形相关的东西在模拟器中以非常的方式工作,有些更快,有些则令人惊讶地慢得多。

也就是说,如果透明背景在设备上确实存在性能问题,则很可能是因为您使用CGContextClearRect()填充了太多像素。我能想到两个解决方案:

  • touchesBegan:withEvent:中,您可以使用CALayer的renderInContext:方法创建基础视图的快照,并将快照绘制为背景而不是清除它。这样,您可以使视图保持不透明状态,从而节省使用其下方视图合成视图的时间。
  • 您可以创建一个代表一条线的单点高CALayer,并将其转换为touchesMoved:withEvent:,以使其结束位置正确。对于表示线末端的点也是如此(CAShapeLayer非常适合)。将涉及一些丑陋的三角函数,但性能将会非常出色。