我很少CAShapeLayers
正在完成圆圈(参考图片)。现在我想在单个触摸上为所有图层设置动画。就像:现在,绿色CAShapeLayer
的中心设置为0度。如果您选择红色CAShapeLayer
,则CAShapeLayer
的中心点将设置为0度。如果您选择黄色CAShapeLayer
,则其中心将在0度进行。记住所有图层都应根据所选图层进行动画处理。我不想使用UIView
。变换。我只想使用CABasicAnimation,CAAnimationGroup
或KeyFrame动画。我正在使用单击手势。
请帮助我。谢谢你。
答案 0 :(得分:0)
这是一个有效的演示
inline static CGPoint CGRectGetCenter( CGRect r )
{
return (CGPoint){ CGRectGetMidX( r ), CGRectGetMidY( r ) } ;
}
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
CGFloat size = 300.0 ;
for( int index =0; index < 10; ++index )
{
RingView * view = [[ RingView alloc ] initWithFrame:(CGRect){ .size = { size, size } } ] ;
view.outerRadius = size * 0.5 ;
view.innerRadius = view.outerRadius - 20.0 ;
view.center = CGRectGetCenter( self.window.bounds ) ;
[ self.window addSubview:view ] ;
size -= 20.0 ;
}
return YES;
}
-(void)ringViewTapped:(RingView*)sender sliceIndex:(NSNumber*)sliceIndex
{
[ UIView animateWithDuration:0.25 animations:^{
sender.transform = CGAffineTransformMakeRotation( -[ sliceIndex doubleValue ] * M_PI_2 ) ;
} ] ;
}
@end
@interface RingView : UIControl
@property ( nonatomic ) CGFloat innerRadius, outerRadius ;
@end
@implementation UIResponder (Send)
-(BOOL)sendMessage:(SEL)message withObject:(id)obj0 withObject:(id)obj1
{
UIResponder * target = self ;
do
{
if ( [ target respondsToSelector:message ] )
{
[ target performSelector:message withObject:obj0 withObject:obj1 ] ;
return YES ;
}
target = [ target nextResponder ] ;
} while( target ) ;
return NO ;
}
@end
@implementation UIColor (RandomColor)
+(UIColor*)randomColor
{
return [ UIColor colorWithHue:((CGFloat)arc4random_uniform( 6 ) / 6.0) saturation:1.0 brightness:1.0 alpha:1.0 ] ;
}
@end
static CGPathRef CGPathCreateWedge( CGFloat innerRadius, CGFloat outerRadius )
{
CGMutablePathRef p = CGPathCreateMutable() ;
CGPathMoveToPoint( p, NULL, 0, innerRadius ) ;
CGPathAddLineToPoint( p, NULL, 0, outerRadius ) ;
CGPathAddArcToPoint( p, NULL, outerRadius, outerRadius, outerRadius, 0.0, outerRadius ) ;
CGPathAddLineToPoint( p, NULL, innerRadius, 0.0 ) ;
CGPathAddArcToPoint( p, NULL, innerRadius, innerRadius, 0.0, innerRadius, innerRadius ) ;
CGPathCloseSubpath( p ) ;
return p ;
}
@interface RingView ()
@end
@implementation RingView
-(void)_ensureSlices
{
if ( self.layer.sublayers.count == 0 )
{
CGPathRef p = CGPathCreateWedge( self.innerRadius, self.outerRadius ) ;
for( int index=0; index < 4; ++index )
{
CAShapeLayer * layer = [ CAShapeLayer layer ] ;
layer.path = p ;
{
CGColorRef c = [ [ UIColor randomColor ] CGColor ] ;
layer.fillColor = c ;
CGColorRelease( c ) ;
}
layer.transform = CATransform3DMakeRotation( (CGFloat)index * M_PI_2 - M_PI_4, 0.0, 0.0, 1.0 ) ;
[ self.layer addSublayer:layer ] ;
}
CGPathRelease( p ) ;
}
}
-(id)initWithFrame:(CGRect)frame
{
self = [ super initWithFrame:frame ] ;
[ self addTarget:nil action:@selector( tapped:event: ) forControlEvents:UIControlEventTouchUpInside ] ;
return self ;
}
-(void)layoutSubviews
{
[ self _ensureSlices ] ;
CGRect bounds = self.bounds ;
self.bounds = (CGRect){ { -0.5f * bounds.size.width, -0.5f * bounds.size.height }, bounds.size } ;
}
-(UIView *)hitTest:(CGPoint)p withEvent:(UIEvent *)e
{
UIView * result = [ super hitTest:p withEvent:e ] ;
if ( result == self )
{
CGFloat r = sqrt( p.x * p.x + p.y * p.y ) ;
if ( r < self.innerRadius || r > self.outerRadius )
{
return nil ;
}
}
return result ;
}
-(IBAction)tapped:(id)sender event:(UIEvent*)event
{
CGPoint p = [ [ [ event touchesForView:self ] anyObject ] locationInView:self ] ;
int index = 0 ;
for( CAShapeLayer * layer in self.layer.sublayers )
{
CGPoint testPoint = [ layer convertPoint:p fromLayer:self.layer ] ;
if ( CGPathContainsPoint( layer.path, NULL, testPoint, false ) )
{
[ self sendMessage:@selector( ringViewTapped:sliceIndex: ) withObject:self withObject:@( index ) ] ;
}
++index ;
}
}
-(void)setOuterRadius:(CGFloat)r
{
_outerRadius = r ;
[[self.layer.sublayers copy ] makeObjectsPerformSelector:@selector( removeFromSuperlayer ) ] ;
[ self setNeedsLayout ];
}
-(void)setInnerRadius:(CGFloat)r
{
_innerRadius = r ;
[[self.layer.sublayers copy ] makeObjectsPerformSelector:@selector( removeFromSuperlayer ) ] ;
[ self setNeedsLayout ];
}
@end