2010-07-13 18 views
1

我很好奇,以實現使用Quarts2D以下功能的「正確」的方法:iPhone Quartz2D呈現擴大圈子

我想有一個觀點,並且能夠在任何座標添加了一圈。一旦我添加該圓圈,它應該以預定的速率擴展;我也想重複這個過程,並有一個數字,如果這些擴大的圈子。

想想導彈司令部:

Yellow spots keep expanding

一般來說,如果我是用C使用SDL寫這篇++或其他一些圖形庫我想:

有一個類來表示一個不斷增長的圓圈「 有一個向量/數組來保存指向我創建的所有「正在增長的圈子」的指針。

所有的圓圈直徑會增加每個tick,並且在我的renderloop中,我會迭代列表並繪製適當的圓圈到我的緩衝區。

然而,這似乎不符合我以前iPhone開發中一般使用視圖的方式。

所以我猜這是一種開放式的,但是對於這樣的事情有沒有一種「正確」的方式?

它是在一個遊戲循環樣式(如上所述),或者我應該爲UIView繼承一個'circle'對象,並覆蓋drawRect?我想我必須通過創建視圖並將其添加到我的主視圖來添加每個圓圈?

最初的調查還給我帶來了CAShapeLayer類的參考,儘管我猜測這可能與實現UIView子類技術非常相似。

回答

2

下面介紹一種方法。下面的代碼添加到您的UIViewController子類,你會得到增長,然後消失了,無論你摸了一圈:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    [self addGrowingCircleAtPoint:[[touches anyObject] locationInView:self.view]]; 
} 

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { 
    if (flag && [[anim valueForKey:@"name"] isEqual:@"grow"]) { 
     // when the grow animation is complete, we fade the layer 
     CALayer* lyr = [anim valueForKey:@"layer"]; 
     CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
     animation.fromValue = [lyr valueForKey:@"opacity"]; 
     animation.toValue = [NSNumber numberWithFloat:0.f]; 
     animation.duration = .5f; 
     animation.delegate = self; 
     lyr.opacity = 0.f; 
     [animation setValue:@"fade" forKey:@"name"]; 
     [animation setValue:lyr forKey:@"layer"]; 
     [lyr addAnimation:animation forKey:@"opacity"]; 
    } else if (flag && [[anim valueForKey:@"name"] isEqual:@"fade"]) { 
     // when the fade animation is complete, we remove the layer 
     CALayer* lyr = [anim valueForKey:@"layer"]; 
     [lyr removeFromSuperlayer]; 
     [lyr release]; 
    } 

} 

- (void)addGrowingCircleAtPoint:(CGPoint)point { 
    // create a circle path 
    CGMutablePathRef circlePath = CGPathCreateMutable(); 
    CGPathAddArc(circlePath, NULL, 0.f, 0.f, 20.f, 0.f, (float)2.f*M_PI, true); 

    // create a shape layer 
    CAShapeLayer* lyr = [[CAShapeLayer alloc] init]; 
    lyr.path = circlePath; 

    // don't leak, please 
    CGPathRelease(circlePath); 
    lyr.delegate = self; 

    // set up the attributes of the shape layer and add it to our view's layer 
    lyr.fillColor = [[UIColor redColor] CGColor]; 
    lyr.position = point; 
    lyr.anchorPoint = CGPointMake(.5f, .5f); 
    [self.view.layer addSublayer:lyr]; 

    // set up the growing animation 
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"]; 
    animation.fromValue = [lyr valueForKey:@"transform"]; 
    // this will actually grow the circle into an oval 
    CATransform3D t = CATransform3DMakeScale(6.f, 4.f, 1.f); 
    animation.toValue = [NSValue valueWithCATransform3D:t]; 
    animation.duration = 2.f; 
    animation.delegate = self; 
    lyr.transform = t; 
    [animation setValue:@"grow" forKey:@"name"]; 
    [animation setValue:lyr forKey:@"layer"]; 
    [lyr addAnimation:animation forKey:@"transform"]; 
} 
+0

很好的解決方案,我喜歡:-) 這種效果不會是如果太有用我想查詢某個特定圓的狀態?雖然我想我可以保留對所有現有圖層的引用,並使用它們來查詢圖層的尺寸等信息(例如,我是否應該處理衝突) – davbryn 2010-07-14 12:17:17

+1

是的,有很多方法可以爲該貓皮膚提供皮膚。看看CALayer的'hitTest:'方法。它默認使用圖層的矩形邊界,但您可以爲展開的圓圈繼承CAShapeLayer,並提供一個明智的關於透明度/幾何的hitTest實現。 – 2010-07-14 12:50:42

+0

輝煌,謝謝! – davbryn 2010-07-14 13:53:08