我对CoreGraphics编程还是有点新鲜,所以请耐心等待。我正在尝试编写一个应用程序,它允许用户用手指擦掉图像。我已经确定了基本功能,但结果是缓慢的,因为每次触摸渲染时都会重新绘制屏幕。我做了一些研究,发现我只能使用UIView的setNeedsDisplayInRect:方法刷新屏幕的一部分。
这会调用drawRect:正如预期的那样,但是我在drawRect中绘制的所有内容:在setNeedsDisplayInRect:之后都会被忽略。相反,rect参数中的区域只是用白色填充。无论我在里面绘制什么,我最终得到的都是一个白色矩形。
从本质上讲,这就是我的工作:
1)当用户触摸屏幕时,此触摸将呈现为蒙版 2)当调用drawRect:时,图像被掩码掩盖
肯定会有一些我很容易忽视的事情吗?
答案 0 :(得分: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] );
}
}
在指纹处理过程中,整个视图以大约20Hz刷新。每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;
}
如果有人能向我解释翻转的原因,我会很感激。
答案 1 :(得分:1)
翻转问题很可能是因为UIKit与Core Graphics相比具有“翻转”坐标。
Apple文档here