Производительность QuartzCore на чистом UIView - PullRequest
1 голос
/ 16 января 2011

У меня есть UIView, где я устанавливаю цвет фона для очистки в методе init.Затем я рисую синюю линию между двумя точками в drawRect.Первая точка - это самое первое прикосновение к представлению, а вторая точка изменяется, когда вызывается функция 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 Ответ

1 голос
/ 17 января 2011

Прежде всего, вы должны тестировать производительность на устройстве, а не в симуляторе. Большинство связанных с графикой вещей работают в очень по-разному в Симуляторе, некоторые из них гораздо быстрее, а некоторые, что удивительно, гораздо медленнее.

Тем не менее, если прозрачный фон оказывается проблемой производительности на устройстве, это, скорее всего, потому, что вы заполняете слишком много пикселей CGContextClearRect(). Я могу думать о двух решениях из головы:

  • В touchesBegan:withEvent: вы можете сделать снимок базового вида (ов) с помощью метода renderInContext: CALayer и нарисовать снимок в качестве фона вместо его очистки. Таким образом, вы можете оставить вид непрозрачным и, таким образом, сэкономить время на компоновке вида с видами под ним.
  • Вы можете создать CALayer высотой в одну точку, представляющий линию, и преобразовать ее в touchesMoved:withEvent:, чтобы ее концы находились в правильных положениях. То же самое касается точек, обозначающих концы линий (CAShapeLayer отлично подходит для этого). Будет задействована какая-то уродливая тригонометрия, но производительность будет отличной.
...