开发者

Rotate an imageView arrow with CAKeyframeAnimation and also have arrow respond to touch events

开发者 https://www.devze.com 2023-04-13 01:04 出处:网络
I have an arrow that spins when the user clicks a button using CAKeyframeAnimation. The position the arrow points to dictates what image is seen by the user.

I have an arrow that spins when the user clicks a button using CAKeyframeAnimation.

The position the arrow points to dictates what image is seen by the user.

This works fine.

The final position of the rotation is selected randomly and sets up the next image for the user when they click the button.

-(void)rotateAnimation
{


    [self setDialStartPosition];
    [self setDialEndPosition];


    //Spin the Arrow

    CALayer *layer = imageView.layer;
    CAKeyframeAnimation *animation;
    animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
    animation.duration = 8;
    animation.cumulative = NO;
    animation.repeatCount = 0;
    animation.values = [NSArray arrayWithObjects:           // i.e., Rotation values for the 3 keyframes, in RADIANS
                        [NSNumber numberWithFloat:[self dialStartPosition] * M_PI], 
                        [NSNumber numberWithFloat:2.5 * M_PI], 
                        [NSNumber numberWithFloat:[self dialEndPosition] * M_PI], nil]; 
    animation.keyTimes = [NSArray arrayWithObjects:     // Relative timing values for the 3 keyframes
                          [NSNumber numberWithFloat:0], 
                          [NSNumber numberWithFloat:.055], 
                          [NSNumber numberWithFloat:1], nil]; 
    animation.timingFunctions = [NSArray arrayWithObjects:
                                 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
                               开发者_运维技巧  // from keyframe 1 to keyframe 2
                                 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], nil]; // from keyframe 2 to keyframe 3
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;

    [layer addAnimation:animation forKey:nil];
    ....

I have this working, but I want the user to be able to move the arrow manually using a touch and have the arrow point in the direction of their finger as they move it around.

When they lift their finger and hit the button, i want the position of the Arrow to dictate what image is then seen by the user. So touchesEnded would have to update the dialStartPosition.

Here is my touches code..

double wrapd(double _val, double _min, double _max)
{
    if(_val < _min) return _max - (_min - _val);
    if(_val > _max) return _min - (_max - _val);
    return _val;
}
    - (void) touchesBegan:(NSSet *)_touches withEvent:(UIEvent *)_event
    {

        UITouch* touch = [_touches anyObject];
        CGPoint location = [touch locationInView:self.view];
        m_locationBegan = location;
    }

    - (void) touchesMoved:(NSSet *)_touches withEvent:(UIEvent *)_event
    {

        UITouch* touch = [_touches anyObject];
        CGPoint location = [touch locationInView:self.view];
        [self updateRotation:location];
    }

    - (void) touchesEnded:(NSSet *)_touches withEvent:(UIEvent *)_event
    {
        UITouch* touch = [_touches anyObject];
        CGPoint location = [touch locationInView:self.view];
        m_currentAngle = [self updateRotation:location];

    }

    - (float) updateRotation:(CGPoint)_location
    {
        float fromAngle = atan2(m_locationBegan.y-imageView.center.y, m_locationBegan.x-imageView.center.x);
        float toAngle = atan2(_location.y-imageView.center.y, _location.x-imageView.center.x);
        float newAngle = wrapd(m_currentAngle + (toAngle - fromAngle), 0, 2*3.14);

        CGAffineTransform cgaRotate = CGAffineTransformMakeRotation(newAngle);
        imageView.transform = cgaRotate;

        return newAngle;
    }

Heres whats happing now..

Before I hit the button I can move the arrow around with a touch the way I want.

When I hit the button it doesn't respond to where I have set the position manually with my touch.

Once the CAKeyframeAnimation plays it no longer will respond to any touches unless I change

animation.fillMode = kCAFillModeForwards;

to

animation.fillMode = kCAFillModeRemoved;

but if I do this it removes the animation after it runs and shows the arrow in the spot I left it when I set it manually.

I'm quite new a programming so any help would be appreciated

Thanks

0

精彩评论

暂无评论...
验证码 换一张
取 消