Проблема с рисованием с помощью Quartz 2d / CGContext и масштабированием - PullRequest
2 голосов
/ 25 июля 2011

Прямо сейчас у нас есть UIScrollView, у которого есть одно подпредставление, UIView. Этот UIView содержит два подпредставления UIImageView, одно из которых является статическим фоновым изображением. Второй UIImageView - это представление для рисования пользователями, которое мы обрабатываем с помощью CGContext.

Мы используем вид прокрутки, потому что фоновое изображение и область рисования большие. Когда пользователь выбирает кнопку, которая входит в режим рисования, он может провести двумя пальцами для прокрутки и одним пальцем для рисования. Это все отлично работает.

Проблема в том, что мы покидаем режим рисования и пытаемся увеличить масштаб. Фоновое изображение отлично масштабируется, но рисование UIImageView поверх него делает что-то странное. Он останется нормального размера на пару секунд, исчезнет, ​​а затем внезапно появится в увеличенном размере. Так что это увеличение, но есть какое-то очень странное поведение и задержка, прежде чем это происходит.

Для справки, вот как мы работаем с чертежом.

/**
 When the user first starts moving the pen
 */
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    isMouseMoved = YES; 
    UITouch *touch = [touches anyObject]; 
    CGPoint currentPoint = [touch locationInView:imageView]; 

    // Setting up the context
    UIGraphicsBeginImageContext(imageView.frame.size);
    [imageView.image drawInRect:CGRectMake(0, 0, imageView.frame.size.width, imageView.frame.size.height)];

    if(isEraserOn){
        CGContextSetLineWidth(UIGraphicsGetCurrentContext(), eraserRadius);
        CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
        CGRect eraserFrame = eraser.frame; 
        eraserFrame.origin.x = currentPoint.x - (eraserRadius/2);
        eraserFrame.origin.y = currentPoint.y - (eraserRadius/2);
        eraser.frame = eraserFrame;

    }else{
        CGContextSetLineWidth(UIGraphicsGetCurrentContext(), penRadius);
        CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), r, g, b, 1.0); 
        CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeNormal);
    }

    CGContextBeginPath(UIGraphicsGetCurrentContext());
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
    CGContextStrokePath(UIGraphicsGetCurrentContext());

    imageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    lastPoint = currentPoint; 
    mouseMoved++; 

    if (mouseMoved == 1) {
        mouseMoved = 0;
    } 
} 

Кто-нибудь знает, что происходит с нашим рисунком UIImageView? Мы думали, что задержка может быть связана с сглаживанием при увеличении, но мы пытались отключить это, и мы все еще сталкиваемся с той же проблемой.

1 Ответ

0 голосов
/ 13 августа 2011

Проблема, вероятно, заключается в том, что вы выполняете все свои рисунки внутри метода touchesMoved, а не в DrawRect, и вызываете метод setNeedsDisplay, чтобы вызывать рисование, когда захотите.В отличном видео от wwdc 2011 было ясно объяснено, что захват CGContext такими методами, как touchesMoved или tochesBegan, является одной из наиболее распространенных причин проблем, связанных с рисованием.Поэтому я бы предложил вам: 1) Не вызывать UIGraphicsGetCurrentContext () в tochesMoved, а делать это в методе DrawRect UIView, на котором рисует пользователь.В touchesMoved вы можете просто сохранить точки, к которым вы прикоснулись, и вы можете сделать то же самое для рисования линий в DrawRect. 2) Отправьте сообщение setNeedsDisplay в UIView в конце touchesMoved.Это гарантирует, что UIView обновляется каждый раз, когда вызывается функция touchesMoved, и может улучшить время отклика.Вы можете попробовать это, даже не пытаясь (1)

Надеюсь, это поможет!

...