2010-04-06 111 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