2010-04-06 78 views
3

我对CoreGraphics编程还是有点新鲜的,所以请耐心等待。我试图编写一个应用程序,它允许用户用手指从图像上擦掉东西。我有固定的基本功能,但结果是迟缓,因为每次触摸时都会完全重新绘制屏幕。我做了一些研究,发现我可以使用UIView的setNeedsDisplayInRect:方法刷新屏幕的一部分。setNeedsDisplayInRect:仅绘制一个白色矩形

这确实会调用drawRect:如预期的那样,但是我在drawRect中绘制的所有内容:在setNeedsDisplayInRect之后:将被忽略。相反,rect参数中的区域只是用白色填充。无论我在里面画什么,最后都是白色的矩形。

从本质上说,这是我做的:

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]); 
    } 
} 

整个刷新视图与在fingerpainting过程大约在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

翻转问题很可能是因为与Core Graphics相比,UIKit具有“翻转”坐标。

Apple文档here