【问题标题】:How Do I Get the Coordinates of an Animated UIImageView如何获取动画 UIImageView 的坐标
【发布时间】:2013-03-07 00:17:28
【问题描述】:

所以,我有一个具有动画 UIImage 的 UIImageView。 UIImageView 本身使用 CAKeyframeAnimation 和 CGMutablePathRef 进行动画处理,以在路径中提供一些随机性。我的问题是当有人点击动画 UIIMageView 时我需要跟踪。

我在这方面已经碰壁了一段时间,似乎我应该将 UITouch 与 UIImage 的表示层在屏幕上的位置进行比较,但我不知道如何获得它的坐标。

所以主要问题是,我如何获得在屏幕上动画的 UIIMageView 的坐标,并将其与点击发生的位置进行比较?

如果我现在按原样运行代码,它会抛出错误:

-[CALayer center]:无法识别的选择器发送到实例 0xa105150

它不再崩溃,但我仍然不知道如何确定 UIImageView 在屏幕上移动时的位置。

我的相关代码如下。任何帮助将不胜感激。

- (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?
    }
}

【问题讨论】:

    标签: ios core-animation coordinates


    【解决方案1】:

    通过对我的 touchesBegan 方法进行以下更改,我终于能够让对象报告它们在屏幕上的位置:

    - (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
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      为什么您希望CALayer 回复center 消息?如果您阅读过它的documentation,您会发现它没有实现名为center 的方法。如果要获取图层的几何中心,请手动计算:

      CGPoint center;
      center.x = CGRectGetMidX(layer.bounds);
      center.y = CGRectGetMidY(layer.bounds);
      

      编辑:看来你想要相对于超级(图层?视图?随便...)的中心:

      CGPoint center;
      center.x = CGRectGetMidX(layer.frame);
      center.y = CGRectGetMidY(layer.frame);
      

      【讨论】:

      • 感谢您解决崩溃问题。我正在重复我在这里其他地方看到的内容,以尝试访问动画层的坐标。更新到代码后,我意识到我仍然只从 UIImageView 接收本地坐标,而不是它在父视图中的位置。关于如何做到这一点的任何提示?
      • @CharlesPayne 使用layer.frame 而不是layer.bounds,从您的问题中不清楚您想要哪一个。
      • 谢谢!我试过了,但它输出的信息与 layer.bounds 完全相同。不知道我在这里缺少什么。动画 UIImageView 显然在移动,但返回的坐标仅与自身相关,与父级无关。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      • 1970-01-01
      • 1970-01-01
      • 2011-03-28
      • 2015-01-01
      相关资源
      最近更新 更多