setNeedsDisplay вызывается только один раз

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

Внутри метода drawRect я рисую линию и вызываю метод линии для увеличения длины строки. Теперь я хочу снова вызвать setNeedsDisplay, чтобы перерисовать линию, чтобы получить анимацию "растущего"..

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

- (void)drawRect:(CGRect)rect {

    for(GameLine *line in _lines) {

        if(line.done) {
            CGContextRef c = UIGraphicsGetCurrentContext();
            CGContextSetLineWidth(c, 5.0f);
            CGContextSetStrokeColor(c, lineColor);

            CGContextBeginPath(c);
            CGContextMoveToPoint(c, line.startPos.x, line.startPos.y);
            CGContextAddLineToPoint(c, line.endPos.x, line.endPos.y);
            CGContextStrokePath(c);
        }else {
            CGContextRef c = UIGraphicsGetCurrentContext();
            CGContextSetLineWidth(c, 5.0f);
            CGContextSetStrokeColor(c, delayColor);

            CGContextBeginPath(c);
            CGContextMoveToPoint(c, line.delayStartPos.x, line.delayStartPos.y);
            CGContextAddLineToPoint(c, line.delayEndPos.x, line.delayEndPos.y);
            CGContextStrokePath(c);

            [line incrementDelayLine];
            [self setNeedsDisplay];
        }
    }
}

_lines - это NSMutableArray со свойством объектов GameLine (неатомное, сохранение).

2 ответа

Решение

Если вам нужна анимация - запустите таймер, после его запуска - настройте любой параметр строки и вызовите setNeedsDisplay

Это ожидаемо.

Когда вы вызываете setNeedsDisplay, вы помечаете представление как нуждающееся в перерисовке. ХОРОШО. Система получает это.
И это будет сделано при следующем запуске основного цикла вашего приложения.

Если вы действительно хотите обновить вид, позвоните:

[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];

сразу после setNeedsDisplay,

Действительно, в документации Apple говорится (выделено мое):

Когда реальное содержание вашего представления изменяется, вы обязаны уведомить систему о том, что ваше представление должно быть перерисовано. Вы делаете это, вызывая setNeedsDisplay вашего представления или setNeedsDisplayInRect: метод представления. Эти методы позволяют системе узнать, что она должна обновить представление во время следующего цикла рисования. Поскольку он ожидает до следующего цикла рисования для обновления вида, вы можете вызвать эти методы для нескольких видов, чтобы обновить их одновременно.

Также посмотрите эти вопросы:

Другие вопросы по тегам