我正在尝试点击五个圆圈中的一个并开始一个动画,该动画将逐渐将所选背景更改为与所拍圆圈相同的颜色。我已经设法让UITapGestureRecognizer响应五个圆圈中的任何一个的轻击手势,但我无法弄清楚如何找出如何识别每个圆圈。
关于UIGestureRecognizer的UIKit框架参考文档说
手势识别器根据特定视图的热门测试进行操作 以及该视图的所有子视图
那个
手势识别器的客户端也可以询问a的位置 通过调用locationInView:或locationOfTouch:inView“。
这让我觉得可能需要将拍过的圆圈制成图像。
但这真的是我需要做的吗?
这是迄今为止的代码
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithRed:240/255.0 green:240/255.0 blue:240/255.0 alpha:1.0];
[self.view setUserInteractionEnabled:YES];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(method:)];
tap.numberOfTapsRequired = 1;
[self.view addGestureRecognizer:tap];
CAShapeLayer *circleLayer1 = [CAShapeLayer layer];
[circleLayer1 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(75.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer1 setStrokeColor:[[UIColor cyanColor] CGColor]];
[circleLayer1 setFillColor:[[UIColor cyanColor] CGColor]];
[[self.view layer] addSublayer:circleLayer1];
CAShapeLayer *circleLayer2 = [CAShapeLayer layer];
[circleLayer2 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(125.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer2 setStrokeColor:[[UIColor redColor] CGColor]];
[circleLayer2 setFillColor:[[UIColor redColor] CGColor]];
[[self.view layer] addSublayer:circleLayer2];
CAShapeLayer *circleLayer3 = [CAShapeLayer layer];
[circleLayer3 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(175.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer3 setStrokeColor:[[UIColor yellowColor] CGColor]];
[circleLayer3 setFillColor:[[UIColor yellowColor] CGColor]];
[[self.view layer] addSublayer:circleLayer3];
CAShapeLayer *circleLayer4 = [CAShapeLayer layer];
[circleLayer4 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(225.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer4 setStrokeColor:[[UIColor magentaColor] CGColor]];
[circleLayer4 setFillColor:[[UIColor magentaColor] CGColor]];
[[self.view layer] addSublayer:circleLayer4];
CAShapeLayer *circleLayer5 = [CAShapeLayer layer];
[circleLayer5 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(275.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer5 setStrokeColor:[[UIColor greenColor] CGColor]];
[circleLayer5 setFillColor:[[UIColor greenColor] CGColor]];
[[self.view layer] addSublayer:circleLayer5];
}
- (void)method:(id)sender {
[UIView animateWithDuration:3.0 animations:^{
self.view.layer.backgroundColor = [UIColor cyanColor].CGColor;
} completion:NULL];
}
为了显示我正在尝试做的事情,我已经设置了方法,因此它将背景图层更改为左侧圆圈的颜色。
但我需要做什么[a]来识别哪个圆圈被点击,[b]将点击的圆点表示为圆圈,这些圆圈也会逐渐改变颜色,以便整个屏幕变为被点击的圆圈的颜色?
答案 0 :(得分:1)
我建议您删除添加到整个视图的UITapGestureRecognizer。 然后为每个CAShapeLayer添加一个名称,以便区分它们:
self.view.backgroundColor = [UIColor colorWithRed:240/255.0 green:240/255.0 blue:240/255.0 alpha:1.0];
[self.view setUserInteractionEnabled:YES];
CAShapeLayer *circleLayer1 = [CAShapeLayer layer];
[circleLayer1 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(75.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer1 setStrokeColor:[[UIColor cyanColor] CGColor]];
[circleLayer1 setFillColor:[[UIColor cyanColor] CGColor]];
[circleLayer1 setName:@"circleLayer1"];
[[self.view layer] addSublayer:circleLayer1];
CAShapeLayer *circleLayer2 = [CAShapeLayer layer];
[circleLayer2 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(125.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer2 setStrokeColor:[[UIColor redColor] CGColor]];
[circleLayer2 setFillColor:[[UIColor redColor] CGColor]];
[circleLayer2 setName:@"circleLayer2"];
[[self.view layer] addSublayer:circleLayer2];
CAShapeLayer *circleLayer3 = [CAShapeLayer layer];
[circleLayer3 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(175.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer3 setStrokeColor:[[UIColor yellowColor] CGColor]];
[circleLayer3 setFillColor:[[UIColor yellowColor] CGColor]];
[circleLayer3 setName:@"circleLayer3"];
[[self.view layer] addSublayer:circleLayer3];
CAShapeLayer *circleLayer4 = [CAShapeLayer layer];
[circleLayer4 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(225.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer4 setStrokeColor:[[UIColor magentaColor] CGColor]];
[circleLayer4 setFillColor:[[UIColor magentaColor] CGColor]];
[circleLayer4 setName:@"circleLayer4"];
[[self.view layer] addSublayer:circleLayer4];
CAShapeLayer *circleLayer5 = [CAShapeLayer layer];
[circleLayer5 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(275.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer5 setStrokeColor:[[UIColor greenColor] CGColor]];
[circleLayer5 setFillColor:[[UIColor greenColor] CGColor]];
[circleLayer5 setName:@"circleLayer5"];
[[self.view layer] addSublayer:circleLayer5];
然后你可以添加这个方法,让你能够检测到触及了CAShapeLayer:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches) {
CGPoint touchLocation = [touch locationInView:self.view];
for (id sublayer in self.view.layer.sublayers) {
if ([sublayer isKindOfClass:[CAShapeLayer class]]) {
CAShapeLayer *shapeLayer = sublayer;
if (CGPathContainsPoint(shapeLayer.path, 0, touchLocation, YES)) {
NSLog(@"Layer's name is: %@",shapeLayer.name);
}
}
}
}
}
现在您可以检测到哪个CAShapeLayer已被触摸,您可以根据需要自定义视图的颜色
答案 1 :(得分:1)
有一种名为locationInView:(UIView *)view
的方法可以帮助您找到位置。您知道所有圈子的位置,并使用方法CGRectContainsPoint(CGRect rect, CGPoint point)
检查位置是否位于任何矩形内部。如果位于其中,您可以检查所选位置与radius
的距离是否centre
。希望这能解决你的问题。
对于Q.(b)我附上了一个你可以参考的样本,
UIColor *stroke = rippleColor ? rippleColor : [UIColor colorWithWhite:0.8 alpha:0.8];
CGRect pathFrame = CGRectMake(-CGRectGetMidX(self.bounds), -CGRectGetMidY(self.bounds), self.bounds.size.width, self.bounds.size.height);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:pathFrame cornerRadius:self.layer.cornerRadius];
// accounts for left/right offset and contentOffset of scroll view
CGPoint shapePosition = [self convertPoint:self.center fromView:nil];
CAShapeLayer *circleShape = [CAShapeLayer layer];
circleShape.path = path.CGPath;
circleShape.position = shapePosition;
circleShape.fillColor = [UIColor clearColor].CGColor;
circleShape.opacity = 0;
circleShape.strokeColor = stroke.CGColor;
circleShape.lineWidth = 3;
[self.layer addSublayer:circleShape];
[CATransaction begin];
//remove layer after animation completed
[CATransaction setCompletionBlock:^{
[circleShape removeFromSuperlayer];
}];
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
scaleAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.5, 2.5, 1)];
CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
alphaAnimation.fromValue = @1;
alphaAnimation.toValue = @0;
CAAnimationGroup *animation = [CAAnimationGroup animation];
animation.animations = @[scaleAnimation, alphaAnimation];
animation.duration = 0.5f;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
[circleShape addAnimation:animation forKey:nil];
[CATransaction commit];
}
[UIView animateWithDuration:0.1 animations:^{
imageView.alpha = 0.4;
self.layer.borderColor = [UIColor colorWithWhite:1 alpha:0.9].CGColor;
}completion:^(BOOL finished) {
[UIView animateWithDuration:0.2 animations:^{
imageView.alpha = 1;
self.layer.borderColor = [UIColor colorWithWhite:0.8 alpha:0.9].CGColor;
}completion:^(BOOL finished) {
if([superSender respondsToSelector:methodName]){
[superSender performSelectorOnMainThread:methodName withObject:nil waitUntilDone:NO];
}
if(_block) {
BOOL success= YES;
_block(success);
}
}];
}];
}`
答案 2 :(得分:1)
正如其他人的答案所指出的那样,你有一些选择,但我认为最简单的方法是检查你的方法你点了什么图层。
您只需要将方法改为:
- (void)method:(UITapGestureRecognizer *)gesture {
CGPoint touchLocation = [gesture locationInView:self.view];
for (id sublayer in self.view.layer.sublayers) {
if ([sublayer isKindOfClass:[CAShapeLayer class]]) {
CAShapeLayer *shapeLayer = sublayer;
if (CGPathContainsPoint(shapeLayer.path, 0, touchLocation, YES)) {
[UIView animateWithDuration:3.0 animations:^{
shapeLayer.strokeColor = [UIColor blackColor].CGColor;
shapeLayer.fillColor = [UIColor blackColor].CGColor;
} completion:NULL];
}
}
}
}
答案 3 :(得分:1)
您不需要在视图中添加任何UITapGestureRecognizer
,只需在图层中添加名称并实施以下方法:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
for (UITouch *touch in touches) {
CGPoint touchLocation = [touch locationInView:self.view];
for (id sublayer in self.view.layer.sublayers) {
if ([sublayer isKindOfClass:[CAShapeLayer class]]) {
CAShapeLayer *shapeLayer = sublayer;
if (CGPathContainsPoint(shapeLayer.path, 0, touchLocation, YES)) {
// This touch is in this shape layer
NSLog(@"Name of layer is: %@",shapeLayer.name);
}
} else {
CALayer *layer = sublayer;
if (CGRectContainsPoint(layer.frame, touchLocation)) {
// Touch is in this rectangular layer
}
}
}
}
}
识别图层后,您可以相应地更改图层的颜色。
或者,如果您的图层数量有限,则可以按照以下方式识别图层:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
for (UITouch *touch in touches) {
CGPoint touchLocation = [touch locationInView:self.view];
if (CGPathContainsPoint(shape1.path, 0, touchLocation, YES)) {
// This touch is in this shape layer
NSLog(@"Name of layer 1 is: %@",shape1.name);
}
if (CGPathContainsPoint(shape2.path, 0, touchLocation, YES)) {
// This touch is in this shape layer
NSLog(@"Name of layer 2 is: %@",shape2.name);
}
if (CGPathContainsPoint(shape3.path, 0, touchLocation, YES)) {
// This touch is in this shape layer
NSLog(@"Name of layer 3 is: %@",shape3.name);
}
if (CGPathContainsPoint(shape4.path, 0, touchLocation, YES)) {
// This touch is in this shape layer
NSLog(@"Name of layer 4 is: %@",shape4.name);
}
if (CGPathContainsPoint(shape5.path, 0, touchLocation, YES)) {
// This touch is in this shape layer
NSLog(@"Name of layer 5 is: %@",shape5.name);
}
}
}