Reputation: 43
So, I have a UIImageView that has an animated UIImage. The UIImageView itself is animated using CAKeyframeAnimation and a CGMutablePathRef to provide some randomness in the path. My problem is that I need to track when someone taps the animated UIIMageView.
I've beaten my head against the wall for a while on this, and it seems like I should be comparing a UITouch to the position of the UIImage's presentation layer on the screen, but I can't figure out how to get the coordinates for it.
So the main question is, how do I get the coordinates for the UIIMageView that is animating across the screen and compare it to where the tap occurred?
If I run the code as is right now, it will throw an error:
-[CALayer center]: unrecognized selector sent to instance 0xa105150
It no longer crashes but I am still at a loss as to how to determine the position of the UIImageView as it is moving across the screen.
My relevant code is below. Any help would be greatly appreciated.
- (void)animateCarrierFish
{
NSInteger getWhichFish = (arc4random()%[self.fishes count]);
NSArray *selectedFish = [NSArray arrayWithArray:[self.fishes objectAtIndex:getWhichFish]];
UIImage *fishName = [selectedFish objectAtIndex:0];
UIImageView *fishCarrier = [[UIImageView alloc] initWithImage:fishName];
fishCarrier.animationImages = selectedFish;
fishCarrier.animationDuration = 1.5;
fishCarrier.animationRepeatCount = 0;
fishCarrier.frame = CGRectMake(0, 0, fishName.size.width*screenScale, fishName.size.height*screenScale);
NSInteger startPoint;
NSInteger endPoint;
NSInteger oppositeMod;
NSInteger fromWhichDirection = (arc4random()%2);
if(fromWhichDirection==1)
{
startPoint = rightEdge;
endPoint = leftEdge;
oppositeMod = -rightEdge;
fishCarrier.transform = CGAffineTransformMakeScale(-1, 1);
} else {
startPoint = leftEdge;
endPoint = rightEdge;
oppositeMod = 0;
}
NSInteger aniSpeed = [self getRandomNumberBetweenMin:15 andMax:20];
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
pathAnimation.duration = aniSpeed;
pathAnimation.calculationMode = kCAAnimationCubic;
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;
CGMutablePathRef pointPath = CGPathCreateMutable();
NSInteger yPoint = [self getRandomNumberBetweenMin:waterLine andMax:seaFloor];
CGPathMoveToPoint(pointPath, NULL, startPoint, yPoint);
NSInteger howManyDips = [self getRandomNumberBetweenMin:2 andMax:4];
int i=0;
for (i = 0; i < howManyDips; i++)
{
yPoint = [self getRandomNumberBetweenMin:waterLine andMax:seaFloor];
NSInteger xMod = [self getRandomNumberBetweenMin:-25 andMax:25];
NSInteger xPoint = (([[UIScreen mainScreen] bounds].size.height/(howManyDips+1))*(i+1)) + xMod + oppositeMod;
if (xPoint <0)
{
xPoint = xPoint*-1;
}
CGPathAddLineToPoint(pointPath, NULL, xPoint, yPoint);
}
yPoint = [self getRandomNumberBetweenMin:waterLine andMax:seaFloor];
CGPathAddLineToPoint(pointPath, NULL, endPoint, yPoint);
pathAnimation.path = pointPath;
CGPathRelease(pointPath);
[fishCarrier.layer addAnimation:pathAnimation forKey:@"pathAnimation"];
[self.view addSubview:fishCarrier];
[fishCarrier startAnimating];
fishCarrier.userInteractionEnabled = YES; // these two lines don't seem to do anything
fishCarrier.multipleTouchEnabled = YES;
fishCarrier.tag=[self.swimmers count];
[self.swimmers addObject:fishCarrier];
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint touch_point = [touch locationInView:self.view];
for (UIImageView *image in self.swimmers) {
// HOW do I get the coordinates in the main view of this sublayer?
}
}
Upvotes: 0
Views: 380
Reputation: 43
I was able to finally get the objects to report where they were on screen using the following changes to my touchesBegan method:
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint startPoint = [touch locationInView:self.view];
CGFloat x = startPoint.x;
CGFloat y = startPoint.y;
//create touch point
CGPoint touchPoint = CGPointMake(x, y);
// loop through the items we're iterested in being tapped on here
for (UIImageView *fish in self.swimmers) {
CGRect fishFrame = [[fish.layer presentationLayer] frame];
if (CGRectContainsPoint(fishFrame, touchPoint)) {
NSLog(@"You hit fish: %u",fish.tag); // do stuff here
}
}
}
Upvotes: 1
Reputation:
Why do you expect CALayer
to respond to the center
message? If you had read its documentation, you would have found out that it doesn't implement a method named center
. If you want to get the geometric center of the layer, calculate it manually:
CGPoint center;
center.x = CGRectGetMidX(layer.bounds);
center.y = CGRectGetMidY(layer.bounds);
Edit: it seems you want the center relative to the super(layer? view? whatever...):
CGPoint center;
center.x = CGRectGetMidX(layer.frame);
center.y = CGRectGetMidY(layer.frame);
Upvotes: 0