CGContextRestoreGState, похоже, не восстанавливает предыдущее состояние

Итак, мне нужно нарисовать серию пунктирных линий вдоль оси. В методе drawRect я вызываю другой метод для рисования оси. В этом методе я сохраняю GState, рисую ось, а затем сохраняю gstate, снова рисую пунктирную линию, когда это необходимо, затем обводку пути восстанавливаю gstate, добавляю что-то к оси заполните путь .. Дело в том, что теперь все это пунктирно ... Кажется, код не отбрасывал шаблон пунктирной линии, когда я восстанавливал gstate ...

   CGContextSaveGState(ctx);
    CGContextSetFillColorWithColor(ctx, [[UIColor whiteColor] CGColor]);
 .......
    //draw a dased line
            CGContextSaveGState(ctx);
            CGContextSetLineWidth(ctx, 1.0);
            CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
            CGFloat const kDashedLinesLength[]   = {1.0f, 0.5f};
            CGContextSetLineDash(ctx, 0.0, kDashedLinesLength, 2);
            CGContextMoveToPoint(ctx, LEFT_EXCLUSION_LENGTH + AXIS_LINE_WIDTH, crtYval);
            CGContextAddLineToPoint(ctx, LEFT_EXCLUSION_LENGTH + AXIS_LINE_WIDTH + self.xAxis.visibleLength , crtYval);
            CGContextStrokePath(ctx);
            CGContextRestoreGState(ctx);
...
   CGContextFillPath(ctx);
    CGContextRestoreGState(ctx);

Как сделать болячку, чтобы дорисовывалась только нужная мне строка???


person user1028028    schedule 03.12.2012    source источник


Ответы (3)


Я не уверен, что не так с вашим кодом, но это не ошибка в восстановлении контекста, которое работает нормально. Вероятно, у вас есть другая ошибка в коде, который вы заменили на .....

Может быть, у вас несбалансированное сохранение и восстановление, что вызовет всевозможные проблемы - я бы проверил это в первую очередь.

Я скопировал и вставил его с минимальными изменениями в метод drawRect пользовательского представления небольшого тестового приложения iOS и запустил его, и я вижу то, что ожидаю.

вот небольшой тестовый код, который работает, как и ожидалось:

- (void)drawRect:(CGRect)rect
{
    // Drawing code

    CGContextRef ctx = UIGraphicsGetCurrentContext();

    CGContextSaveGState(ctx);
    CGContextSetFillColorWithColor(ctx, [[UIColor blackColor] CGColor]);
    CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);
    CGContextSetLineWidth(ctx, 2.0);

    //draw a dased line
    CGContextSaveGState(ctx);
    CGContextSetStrokeColorWithColor(ctx, [UIColor blueColor].CGColor);
    CGFloat const kDashedLinesLength[]   = {1.0f, 2.0f};
    CGContextSetLineDash(ctx, 0.0, kDashedLinesLength, 2);
    CGContextMoveToPoint(ctx, 100, 100 );
    CGContextAddLineToPoint(ctx, 100, 200);
    CGContextStrokePath(ctx);
    CGContextRestoreGState(ctx);


    CGContextMoveToPoint(ctx, 200, 100 );
    CGContextAddLineToPoint(ctx, 200, 200);
    CGContextStrokePath(ctx);

    CGContextFillPath(ctx);
    CGContextRestoreGState(ctx);
}

И это образец вывода:

скриншот

person Dad    schedule 08.12.2012

Вы должны быть осторожны, чтобы всегда точно сбалансировать сохранение с восстановлением. У меня были ситуации, когда у меня было слишком много одного или другого в совершенно другом месте моего приложения. Поскольку iOS частично повторно использует контексты, это может оставить графический контекст в странном состоянии.

Вы должны искать в своем исходном коде все экземпляры сохранения и восстановления и подсчитывать, если их одинаковое количество.

person Cocoanetics    schedule 10.12.2012

Кажется, я знаю твою проблему. Посмотрите на это так: линия не рисуется, пока вы не обведете контур. Таким образом, какой бы шаблон ни действовал, когда вы вызываете CGContextAddLineToPoint (например), это не имеет значения. Когда вы вызываете CGContextAddLineToPoint, вы не рисуете линию, вы просто строите путь. Я предполагаю, что ваша подпрограмма для рисования осей не обводит их. Оси не рисуются до тех пор, пока вы позже не вызовете CGContextStrokePath, и в этот момент действует пунктирный шаблон.

person bugloaf    schedule 11.12.2012