UIView animation not going back to original state - objective-c

I am trying to make UIView glow back and forth twice. My animation below works but just after it has finished it goes to the state that I animated it to, and not the original. I set autoreverses to YES so why is it not going back to original state ?
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationRepeatCount:2];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationDuration:0.3];
[UIView setAnimationBeginsFromCurrentState:YES];
textDetailView.layer.backgroundColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:0.3].CGColor;
[UIView commitAnimations];

The animation reverses but the value doesn't. After the animation completes it removes itself from the view (actually from the views layer) and the view appears to have the properties that have been set on it.
You could set the value back in a completion block or in the selector for the older UIView animation that you are using.
Alternatively, for animations where the value doesn't change you could benefit from using Core Animation (which doesn't hangs the value (after the animation the view goes bak to its original state)).
You would need to import QuartzCore.framework and include QuartzCore/QuartzCore.h to get it to work.
The could would also need to be updated to something like this:
CABasicAnimation *myColorAnimation = [CABasicAnimation animationWithKeyPath:#"backgroundColor"];
[myColorAnimation setAutoreverses:YES];
[myColorAnimation setRepeatCount:2];
[myColorAnimation setDuration:0.3];
[myColorAnimation setToValue:(id)[myColor CGColor]];
// the default "from value" is the current value
[[textDetailView layer] addAnimation:myColorAnimation forKey:#"myColorKey"];

Related

How to check if UIView is at coordinates

I have a tableView with textFields inside of them, and I have animation that slides the tableView up when the textFieldDidBeginEditing method is called. Here is my code:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
self.headerView.alpha = 0.2;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.18];
[UIView setAnimationDelegate:self];
self.theTableView.frame = CGRectMake(0, 130, 320, 209);
[UIView commitAnimations];
}
The problem is that the animation happens whenever one of the cells is tapped, but I only want it to happen the first time a cell is tapped. So I was thinking that I should make an if statement that checks whether the tableView is at the (0, 130) coordinates. Does anyone know how I would do this?
For an exact comparison, CGPointEqualToPoint() will suffice. For a broader comparison (checking if the rect of the view contains the given point), CGRectContainsPoint() is perfect.
Of course, all of this is a little much. Subclass your view and keep a flag on it to track whether or not they've been slid up. Not only does it keep your code more self-contained, but it keeps the logic for the view out of your controller.

Why does view draw under the task bar after a custom scale and flip animation?

Same code as in a previous question, but a different issue.
I've created a custom animation to add a view controller to a UINavigationController. This code scales a view to 80% the original size, then flips it, then scales it back up to its original size:
[UIView animateWithDuration:scaleDuration delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
// Scale the controllers' views down.
self.view.transform = CGAffineTransformScale(self.view.transform, 0.8, 0.8);
} completion:^(BOOL finished) {
// Transition to the new view and push on the new view controller.
[UIView transitionWithView:self.view duration:1 options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionTransitionFlipFromLeft animations:^{
[self pushViewController:viewController animated:NO];
} completion:^(BOOL finished) {
[UIView animateWithDuration:scaleDuration delay:0 options:UIViewAnimationOptionCurveLinear animations:
^{
// Scale back to the original size.
self.view.transform = CGAffineTransformScale(self.view.transform, 1.25, 1.25);
} completion:nil];
}];
}];
The issue is that, when the animation completes, the new view is displayed very nicely, except that it is drawn under the task bar. That is, it draws in at screen origin 0,0, rather than 0,20. The "Status Bar" option is set in IB (to "Black"), and, naturally, this does not happen if I use a standard UINavigationController push animation, only my custom one. If I rotate the device after the animation, the redraw on rotation moves it to the proper place. But how do I get it to do that in the first place?
As an added wrinkle, it does not draw under the task bar if I move the pushViewController:animated: call a line down to the completion: block (though then the view appears to flip to itself and then suddenly show the new view, of course).
I found the only work around so far is hide the navigationbar and then show it.
after you set your transform, add following 2 lines:
[self setNavigationBarHidden:YES];
[self setNavigationBarHidden:NO];
It's ugly but works, I am also looking for a better solution.
note: layoutsubview, setNeedsLayout won't work.

How can I touch and drag an animated image? here's my animation code:

- (void)viewDidLoad
{
[super viewDidLoad];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:4];
[UIView setAnimationRepeatCount:50];
[UIView setAnimationRepeatAutoreverses:NO];
CGPoint abc =chem1.center;
abc.y= 480;
chem1.center=abc;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:4];
[UIView setAnimationRepeatCount:50];
[UIView setAnimationRepeatAutoreverses:NO];
CGPoint def =chem2.center;
def.y= 480 ;
chem2.center=def;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:4];
[UIView setAnimationRepeatCount:50];
[UIView setAnimationRepeatAutoreverses:NO];
CGPoint hij =nat1.center;
hij.y= 480;
nat1.center=hij;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:4];
[UIView setAnimationRepeatCount:50];
[UIView setAnimationRepeatAutoreverses:NO];
CGPoint klm =nat2.center;
klm.y= 480;
nat2.center=klm;
}
I'd really appreciate the help
There are two parts to your question: how to tap an animated image and how to drag an image.
How to tap an animated image.
Background
When you are animating a view (or more accurately its layer) the property that you change (in your case the position (by setting center)) is changed to its final value right away. If you only animate (like with a CABasicAnimation, then the properly might not change at all.
This means that if you try to tap the view (or layer) it will be at the position that you moved it to (its final position (despite any duration or repeat count of the animation).
Hit test a moving layer
To be able to hit test something that is moving you need to hit test against the presentationLayer of the layer of the view that you are trying to tap.
CGPoint touchPoint = [gestureRecognizer locationInView:[self view]];
if ([[[[self movingView] layer] presentationLayer] hitTest:touchPoint]) {
// Yeah, you hit the moving (animating) layer!
}
Now that the user has tapped a moving view (image in your case) you can begin to handle the drag.
How to drag an image
When you are dragging an image you move the layer to wherever the users finger is dragging the image.
Remove to animation that moves the view
First you should cancel the ongoing animation for that view (having a name for the animation enables you to cancel only one animation.
[[[self movingView] layer] removeAllAnimations];
Or if you have set a name to the movement animation.
[[[self movingView] layer] removeAnimationForKey:#"nameOfMovingAnimation"];
Move the view to the location of the users finger
Next you should (continuously) update the position of the view as the user moves its finger. You should not animate this since it will increase the time between the movement of the finger and the view and will make it seem like your application is lagging. Animating while dragging does not make it look smooth.
Note: since your question doesn't say what you want to do once the user are dragging the images or what happens when they drop them. I can't go much further in the explanation.
Need more help?
Search the web (or StackOverflow) for something like: "iOS drag view" and you will probably find more information about how to drag your imageViews.
Otherwise ask another question on StackOverflow once you have gotten this far (i.e. you can tap on the moving images and they stop moving).

Flipping a view that is contained on a view setup

I currently have a xib that is a standard view that has another view contained on top. I want the user to be able to click on this subview, and then have this subview flip over when pressed. I currently have code that flips the view around, but since I'm not explicitly assigning a new view, it just flips over and displays the same view. Here is my code when the button is pressed:
- (IBAction)flipCard:(id)sender
{
NSLog(#"Subview button was clicked!");
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:self.frontOfView
cache:YES];
[UIView commitAnimations];
}
The biggest question is how to set this up. Do I need to create an entire view programmatically and then just call [[self view] addSubview: backOfView]*? Or is there a way to do this with interface builder?
*Note I haven't actually create a "backOfView" object, I'm not sure how I should create one at this point.
Try this one?
[UIView transitionFromView:self.frontOfView
toView:self.backOfView
duration:0.4f
options:UIViewAnimationOptionTransitionFlipFromLeft
completion:nil];

Change backside color of uiview when using Curlup animation

I have an uiview which i add a transition that removes it from an uiwindow using curlup animation. When the animation occurs the backside of the view is white...i would like to change the color of it or even put some of my own texture. Any help appreciated.
[UIView beginAnimations: #"Curl up" context:nil];
// wait for time before begin
[UIView setAnimationDelay:wait];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:viewToCurlUp cache:YES];
// druation of animation
[UIView setAnimationDuration:duration];
[UIView commitAnimations];
As far as I know, it is not possible to create a texture (ie: your own image) on a UIView. The color of 'back of the curl' should correspond to the background color you have set for your UIView. You can do this in the inspector in Interface Builder, or programmatically like so:
[view setBackgroundColor:[UIColor greenColor]];
where view is the UIView of interest. Use the appropriate color, of course.
Hope that helps.
Apple engineers responded that this is not possible in my case. I have asked them a few days ago.