views:

192

answers:

3

I have a UIView doing a simple animation. It adjusts its y position from 100 to 130 and then reverses. I want it to keep repeating so I have the repeat counter set to 999. Upon user input, I want to take the same UIView and adjust the x position. This is done by means of another UIView animation. The problem is that when the 2nd animation starts, the 1st animation (that goes from 100 to 130 in the y direction) just ends abruptly (as I read that it should). Is there any way to get the final position of the y coordinate of that UIView before it was ended? I would ideally like to have the UIView stay in the same y position that it was in while I translate the x coordinates.

Summary: UIView moves in the y direction from 100-130, reverses and repeats until user input is received. Once received, animation is cut short and UIView jumps to y=130. I would like a way to find out what the final y value was before the animation was cut short, so when new animation with x translation is used, the UIView will not jump to 130, but remain the same position it was in when the 1st animation ended.

I can't seem to see anything that would let you do that. It appears to me that once you set the animation in motion with UIView, then it (and all current state changes) are out of your hands and will only be "returned" to your control and availability once the animation is done and at the designated end point. Is this correct? Any insight would be appreciated. Thank you for your time.

A: 

I'm not sure if this is exactly what you want, but UIView's setAnimationBeginsFromCurrentState: used inside a beginAnimations block will cause the x animation to start wherever the y is in progress.

David Kanarek
I'm reading up on it now. Ideally, I would not want to stop my y-direction animation, only introduce a x-based animation upon user input.
MarcZero
I've never used this, so I don't know if it will kill the other one or not, but it's worth trying. If it does kill it, you could make the new animation block include the y animation as well.
David Kanarek
The problem seems to be that once I start the y animation, it lists the y variable at the end (130) immediately, even when it is animating it back and forth during that time. There isn't too much out there regarding how to implement the setAnimationBeginsFromCurrentState. It seems to allow the y to remain the same entering into the x animation, but I can't just pass the new x coordinates in, I have to pass in a CGPoint, including the y component which I only have access to the final y position (and which also kills the animation part of the y component).
MarcZero
A: 

Perhaps for what you are trying to accomplish it would benefit to exercise a little more control over the animation. For this task I would suggestion using an NSTimer scheduled at whatever interval works best for you (1/30 to 1/60) and just adjust the UIView position every time the timer fires. This way you can always access the X and Y components of the view's position.

Something like:

- (void)timerFired:(NSTimer *)timer {
    CGPoint p = view.center;

    if (p.y >= 130.0) {
        positiveMovement = NO;
    }
    else if (p.y <= 100.0) {
        positiveMovement = YES;
    }

    if (positiveMovement)
        p.y++;
    else
        p.y--;

    view.center = p;
}

positiveMovement would just be a BOOL instance variable. You could also then just directly adjust the X value of the view's position elsewhere with user input and it would update accordingly.

Matthew McGoogan
This is what I originally considered, but I am(was) attempting to do this with the built-in UIView or other features. My main reason so far for not doing something like this was for the built in "curve" of the animations so they would not be jerky. I could huff it out with code on my own if I have to but I was trying to figure out how to do it with the built-in frameworks.
MarcZero
+4  A: 

You're looking for the "presentation layer".

Each UIView is rendered using a Core Animation layer, which is accessible from UIView's layer property.

CALayer has a presentationLayer method, which returns a CALayer that represents "a close approximation to the version of the layer that is currently being displayed".

So, to get the current position of your view:

CGRect currentViewFrame = [[myView.layer presentationLayer] frame];
Darren
I ended up making a new UIView in UI Builder as a parent and put my items on there as children. I then move the parent UIView layer in the x direction upon user input which leaves the children items to keep running in the y direction on top the parent as it moves. Although I did not implement your answer, it appears to directly answer the question I posed so I will mark it as answered for now.
MarcZero