04a-Clipped Views

iPhone SDK開發範例大全第二章之四(4/14):2009年08月25日星期二

iPhone SDK開發範例大全即iPhone Developer's CookBook的中文譯本,程式可由erica網站下載。第二章講View(視圖),程式共有十四個:

本文講第四個程式04a-Clipped Views:

(A)這個程式會顯示16個相同的小圓(小圓內是個image、在icon.png內)在iPhone螢幕,並且每按Randomize可以移動全部16個小圓一次。見下第一圖及下第二圖(Randomize之後),小圓的位置改變了:

 

(B)重點是,如何顯示出圓形(而非方形)?見下圖、drawRect method,drawRect是UIView的一個method,在本程式中overwrite UIView的default drawRect。

CGContextRef context = UIGraphicsGetCurrentCOntext(); //Look at UIView 、drawRect、 UIGraphicsGetCurrentCOntext

先找到context、繪畫環境(背景),就是個畫畫的畫布 ( drawing destination ),有bitmap context PDF oontextwindow context 、layer context ( CGLayerRef "CDLayer.h in Core Graphics.framework", CFType-->CGLayer--- CGLayer Drawing)。

CGMutablePathRef path = CGPathCreateMutable();//回傳CGMutablePathRef,CGMutablePathRef是pointer to CGPath

找一個path,allocate path。

CGPathAddEllipseInRect(path, NULL, bounds);//NULL表示不用CGAffineTransform。也就是,在長方形bounds(CGRect)內畫個橢圓(path)--如果是正方形,就是圓。

CGAffineTransform:就是個3x3的matrix來做Affine(姻親) Transform。 若是NULL,就不用做CGAffineTransform,就不用乘下列matrix。

  • struct CGAffineTransform {CGFloat a ; CGFloat b ; CGFloat c ; CGFloatda ; CGFloat tx ; CGFloat ty ; }
  • [x' y' z'] = [x y z] [r1 r2 r3](of transpose)// r1 r2 r3各為一個row
  • r1 = [ a b 0 ] r2 = [c d 0] r3 =[tx ty 1]

也就是:

  • x' = ax + cy +tx
  • y' = bx + dy +ty

CGContextAddPath(context, path):在CGContextRef內,將path加入CGContext原有的path內,

注意:次序很重要,最後加入的path在最下面,見“The Page”

CGContextClip(context);

[LOGO drawInRect:bounds];

CFRelease(path);

這三行finish up。

所有的drawRect功效,都是iPhone Quartz 2D Graphics engine做的,CGPathAddEllipseInRec等均是其function call, 有關Quartz 2D的種種如下:

API(Application Programming Interface):如何實際上使用Quartz 2D?可以看--Drawing to a Graphic Context in iPhone OS。 概念如下

 

(C)誰call drawRect?

答:iPhone OS。經設break point。知道一路上都沒人call drawRect,到了applicationDidFinishLaunching執行完之後,drawRect才被呼叫,一共呼叫了十六次,看下兩圖上方星號處,那是drawRect程式裡的兩個local variables,context及path,有趣的是context每次(十六次)的值均相同0x455d10,應該是 context 每次均point同一CGContext。path則不盡相同。