2010-04-06 6 views
3

Я все еще немного свежий для программирования CoreGraphics, поэтому, пожалуйста, несите меня. Я пытаюсь написать приложение, которое позволяет пользователю вытирать изображение пальцем. У меня есть основная функциональность, пригвожденная вниз, но результат вялый, так как экран полностью перерисовывается каждый раз при нажатии. Я провел некоторое исследование и выяснил, что я могу обновить только часть экрана, используя метод setNeedsDisplayInRect: UIView.setNeedsDisplayInRect: рисует только белый прямоугольник

Это вызывает drawRect: как и ожидалось, однако все, что я рисую в drawRect: после setNeedsDisplayInRect: игнорируется. Вместо этого область в прямом параметре просто заполняется белым цветом. Независимо от того, что я рисую внутри, все, что у меня получается, - это белый прямоугольник.

В сущности, это то, что я делаю:

1), когда пользователь касается экрана, это прикосновение визуализируется в маску 2), когда DrawRect: называется, изображение маскируется с этой маской

Должно быть, что-то простое, что я не замечаю, конечно?

ответ

2

Я нашел решение, однако он все еще избегает меня, как именно это работает. Вот код:

Этот метод переворачивает заданный прямоугольник в том же порядке, в котором преобразование координат в контексте флипы системы координат контекст:

- (CGRect) flippedRect:(CGRect)rect 
{ 
    CGRect flippedRect = rect; 

    flippedRect.origin.y = self.bounds.size.height - rect.origin.y - rect.size.height; 

    return CGRectIntersection(self.bounds, flippedRect); 
} 

Это рассчитает прямоугольник который должен быть обновлен от прикосновения место нахождения. Обратите внимание, что прямоугольник получает переворачивается:

- (CGRect) updateRectFromTouch:(UITouch *)touch 
{ 
    CGPoint location = [touch locationInView:self]; 

    int d = RubbingSize; 

    CGRect touchRect = [self flippedRect:CGRectMake(location.x - d, location.y - d, 2*d, 2*d)]; 

    return CGRectIntersection(self.frame, touchRect); 
} 

В оказывают прикосновение на «перевернутые» обновление прямоугольниками принуждают:

- (void) renderTouch:(UITouch *)touch 
{ 
    // 
    // Code to render into the mask here 
    // 

    if (m_updateRect.size.width == 0) 
    { 
     m_updateRect = [self updateRectFromTouch:touch]; 
    } 
    else 
    { 
     m_updateRect = CGRectUnion(m_updateRect, [self updateRectFromTouch:touch]); 
    } 
} 

Весь вид обновляется приблизительно 20Гц в процессе рисования пальцами. Следующий метод вызывается каждый 1/двадцатый второй и представляет прямоугольник для рендеринга:

- (void) refreshScreen 
{ 
    if (m_updateRect.size.width > 0) 
    { 
     [self setNeedsDisplayInRect:[self flippedRect:m_updateRect]]; 
    } 
} 

Вот вспомогательный метод для сравнения с прямоугольниками:

BOOL rectIsEqualTo(CGRect a, CGRect b) 
{ 
    return a.origin.x == b.origin.x && a.origin.y == b.origin.y && a.size.width == b.size.width && a.size.height == b.size.height; 
} 

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

- (void)drawRect:(CGRect)rect 
{ 
    BOOL drawFullScreen = rectIsEqualTo(rect, self.frame); 

    // Drawing code 

    CGContextRef context = UIGraphicsGetCurrentContext(); 

    // Turn coordinate system around 

    CGContextTranslateCTM(context, 0.0, self.frame.size.height); 

    CGContextScaleCTM(context, 1.0, -1.0); 

    if (drawFullScreen) 
    { 
     // draw the full thing 
     CGContextDrawImage(context, self.frame, self.image); 
    } 
    else 
    {  
     CGImageRef partialImage = CGImageCreateWithImageInRect(self.image, [self flippedRect:m_updateRect]); 

     CGContextDrawImage(context, m_updateRect, partialPhoto); 

     CGImageRelease(partialImage); 
    } 

     ... 

    // Reset update box 

    m_updateRect = CGRectZero; 
} 

Если кто-то может объяснить мне, почему работает флиппинг, я был бы признателен.

1

Проблема с переворачиванием, скорее всего, из-за того, что UIKit имеет «перевернутую» координату по сравнению с Core Graphics.

Документация компании Apple here

Смежные вопросы