2010-07-13 37 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