Я нашел решение, однако он все еще избегает меня, как именно это работает. Вот код:
Этот метод переворачивает заданный прямоугольник в том же порядке, в котором преобразование координат в контексте флипы системы координат контекст:
- (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;
}
Если кто-то может объяснить мне, почему работает флиппинг, я был бы признателен.