Простое приложение для рисования iPhone с Quartz 2D - PullRequest
3 голосов
/ 09 августа 2009

Я делаю простую программу для рисования на iPhone в качестве личного побочного проекта.

Я фиксирую событие прикосновения в подклассе UIView и отображаю фактический материал в отдельном CGLayer. После каждого рендеринга я вызываю [self setNeedsLayout], а в методе drawRect: я рисую CGLayer в контексте экрана.

Все это прекрасно работает и прилично работает для рисования прямоугольников. Тем не менее, я просто хочу простой режим "от руки", как и многие другие приложения для iPhone.

Я подумал сделать это, создав CGMutablePath, и просто:

CGMutablePathRef path;
-(void)touchBegan {
    path = CGMutablePathCreate();
}
-(void)touchMoved {
    CGPathMoveToPoint(path,NULL,x,y);
    CGPathAddLineToPoint(path,NULL,x,y);

}
-(void)drawRect:(CGContextRef)context {
      CGContextBeginPath(context);
      CGContextAddPath(context,path);
      CGContextStrokePath(context);
}

Тем не менее, после рисования в течение более 1 секунды, производительность ухудшается ужасно.

Я бы просто нарисовал каждую линию в CGLayer за пределами экрана, если бы не переменная непрозрачность! Непрозрачность менее 100% приводит к тому, что на экране остаются точки, соединяющие линии. Я посмотрел на CGContextSetBlendingMode (), но, увы, не могу найти ответ.

Может ли кто-нибудь указать мне правильное направление? Другие приложения для iPhone могут делать это с очень хорошей эффективностью.

Ответы [ 2 ]

1 голос
/ 11 ноября 2009

То, что сказал СанХоло - плюс вы можете ограничить добавление очков, поэтому он добавляет новую точку не чаще, чем, скажем, каждые 10 мс (вам нужно играть с интервалом). Вы можете сделать это с помощью простого таймера.

Кроме того, как вы указываете представлению, что оно должно перерисовывать себя? Возможно, вы захотите ограничить это тоже - и это может происходить с более длительным интервалом, чем захват точек (например, захватывать точки не чаще, чем каждые 10 мс, и перерисовывать не чаще, чем каждые 200 мс - опять же, вам нужно играть с числами) .

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

1 голос
/ 11 ноября 2009

Проблема в том, что с CGStrokePath() текущий изменяемый путь закрывается и рисуется, и при перемещении пальца создается новый путь. Таким образом, вы, вероятно, в конечном итоге получите множество путей для «сеанса» одним касанием, по крайней мере, именно это, похоже, делает ваш псевдокод.

Вы можете попытаться начать новый изменяемый путь, когда касания начинаются, используйте CGAddLineToPoint(), когда касания перемещаются, и заканчивайте путь, когда касания заканчиваются (так же, как показывает ваш псевдокод). Но в методе рисования вы рисуете копию текущего изменяемого пути, и фактический изменяемый путь все еще удлиняется до конца касаний, поэтому вы получаете только один путь за весь сеанс касания. После окончания касаний вы можете окончательно добавить путь - например, вы можете поместить все пути в массив и выполнить итерации по ним в методе рисования.

...