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