How to not animate transformation? - objective-c

How can I not animate transformation during moving some frame? I have some block with animation:
[UIView animateWithDuration:.2 animations:^{
self.center = [ViewController fitPointToNet:self.center];
[self.delegate repaint];
}];
And repaint call paintInView method. This method draw some figure (e.g. line) and rotate them. I want to animation look like line move to destination point - now it move and rotate.
- (void)paintInView:(UIView*)view
{
//some drawing code
line.transform = CGAffineTransformMakeRotation(M_PI);
//some drawing code
}
Anyone can help?

You're calling the repaint method from within the animation block - so any changes to animatable properties of any view will be animated.
You should call that method from the completion block of the animation instead - use the animateWithDuration:animations:completion method instead of the one you are using now.
This will perform the transform without animating, after the animation has completed.

Related

Apply CALayer changes to UIView

I have a UIView. I applied the animation to its CALayer.
[view.layer addAnimation:groupAnimation forKey:name];
I want the final state of the layer to be the state of the UIView after the animation. Let's say I rotated by 45degrees and moved to a new position using the layer; is it possible for my view to be in that state after the animation? Because right now, after the animation, it goes back to the original state of the UIView. I hope to receive some help with this. Thanks.
The thing to understand is that layer animation is just animation; it's merely a kind of temporary "movie" covering the screen. When the animation ends, the "movie" is removed, thus revealing the true situation. It is up to you to match that situation with the final frame of the movie.
UIView animation does this for you, to a great extent. But layer animation leaves it entirely up to you.
Thus, let's say you animate a position change; doing something so that the layer or view actually is where you animated to is completely up to you.
The usual thing is to perform the changes yourself as a separate set of commands. But be careful not to do anything that might trigger implicit layer animation, as this will conflict with the animation you are trying to perform explicitly.
Here's example code (not related to yours, but it does show the general form):
CAAnimationGroup* group = // ...
// ... configure the animation ...
[view.layer addAnimation:group forKey:nil];
// now we are ready to set up the view to look like the final "frame" of the animation
[CATransaction setDisableActions:YES]; // do not trigger implicit animation by mistake
view.layer.position = finalPosition; // assume we have worked this out
When animating a CALayer or using a CAAnimationGroup, the following properties must be set, e.g.:
groupAnimation.removedOnCompletion = NO;
groupAnimation.fillMode = kCAFillModeForwards;
See also: After Animation, View position resets
Also note that it may be helpful to apply animations directly to the view itself, rather than by accessing the view's layer. This is accomplished using animation blocks, which I have found to be very useful.
Block style animations can be customized in many ways, but here's a basic example, which could be invoked within a function when your view needs to animate:
- (void) animateMyView
{
CGRect newViewFrame = CGRectMake(x,y,w,h);
[UIView animateWithDuration:0.5
delay:0
options: (UIViewAnimationOptionCurveLinear )
animations:^{
self.myView = CGAffineTransformMakeRotation (45);
[self.myView setBounds:newViewFrame];
}
completion:NULL];
}
For more information, see Apple's documentation on View Animation.

Move to new view controller after animation stops

I'm new to programming Xcode/objectiveC and this questions seems like it should be painfully obvious but I cannot find an answer; how do i move to a different view controller after an animation completes (without a button or other user interaction). in other words go back to the "home" screen automatically after it finishes. right now the image that is animated just stops moving and stays there after the animation finishes and i'm stuck in that viewController.
i'm guessing the coding should have something to do with the selector but i'm not sure
[UIView setAnimationDidStopSelector:#selector ???];
thanks!
UIView's animateWithDuration has a completion block in which you can put code that is executed when the animation is completed.
[UIView animateWithDuration:duration
animations:^{
animations
}
completion:^(BOOL success) {
[self performSegueWithIdentifier:#"YOUR_SEGUE"];
}];

Rotating after an animation

I have a UIViewController subclass that can display animations (mostly changing alphas on imageview subviews). If an animation is occurring when the device is rotated, I would like the rotation animation to occur after the current animation block completes. How can I make this happen?
When you call a method that animated an image, set some BOOLean value to NO and conditionally allow rotation in the -shouldAutorotateToInterfaceOrientation method. Something like this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if (!someBool)
return NO;
return YES;
}

Consecutive animations using nested animation blocks

I'm looking for a way to implement consecutive animations using nested animation blocks.
Somewhat complicated by happening inside a UIScrollView, the size of three UIImageViews (there are many images, and as I scroll through them I constantly swapping out the images in the UIImageViews).
When a scroll is finished, I want to switch out the image in the (visible) middle UIImageView, three times, then back to the original view. I'm trying it thus:
- (void) doAnimation {
// get the animation frames, along with the current image
NSString *swap1 = #"first.png";
NSString *swap2 = #"second.png";
UIImage *original = currentPage.image;
UIViewAnimationOptions myOptions = UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction;
[UIView animateWithDuration:2.0 delay:2.0 options:myOptions
animations:^{ [currentPage setImage:[UIImage imageNamed:swap1]]; }
completion:^(BOOL finished) {
[UIView animateWithDuration:2.0 delay:2.0 options:myOptions
animations:^{ [currentPage setImage:[UIImage imageNamed:swap2]]; }
completion:^(BOOL finished) {
[UIView animateWithDuration:2.0 delay:2.0 options:myOptions
animations:^{ [currentPage setImage:[UIImage imageNamed:swap1]]; }
completion:^(BOOL finished) {
[currentPage setImage:original]; }]; }]; }];
}
When I run this, there is no duration, no delay, it all happens at once, almost too fast for the eye to see. Could this be because "currentPage" is a UIImageView? (Similar to this question?)
There's no delay because UIImageView.image isn't an animateable property. As such, the UIView animation machinery will have no animations to set up and will just call your completion block immediately.
What sort of animation did you expect? You can attach a CATransition object to the underlying layer to get a simple cross-fade, Just use [imageView.layer addAnimation:[CATransition animation] forKey:nil] to get the crossfade with the default values (you can customize the timing by modifying properties of the CATransition before attaching it to the layer). To achieve the subsequent animations, you can either use the delegate property of CAAnimation (CATransition's superclass) to learn when it's done and fire your second one, or you could just use -performSelector:withObject:afterDelay: to start your next animation step after a user-defined delay. The delegate method is going to be more accurate with regards to timing, but the performSelector method is a bit easier to write. Sadly, CAAnimation doesn't support a completion block.
Another approach for you to transition from one image view to another is by using the block animation function transitionFromView:toView:duration:options:completion as discussed in "Creating Animated Transitions Between Views". You would do this instead of animateWithDuration to change images.

Clearing content of NSWindow

I have used the (void)drawRect:(NSRect)dirtyRect to draw triangles, which is displayed in a NSWindow. My triangles are drawn, but the problem is removing them from the window. I have to figure out how to remove/clear the lines that are drawn from the strokeLineFromPoint:toPoint using a simple method.
Thanks in advance!
You have to create a view and set it to the view property of the NSWindow. Then, draw using the view's drawRect method. The NSWindow does not have a drawRect method. Also, If you want to change the drawing, you have to redraw the part or the entire view.
You need to use the setNeedsDisplay method to redraw the view. So, you'd need something like this:
-(void) deleteStuff{
removeTriangles = YES; //Boolean value
[myView setNeedsDisplay];
}
Then, inside the drawRect function, simply put all your drawing code inside an if statement.
(void)drawRect:(NSRect)dirtyRect{
if(!removeTriangles){
//Rest of drawing code
}
}
Don't forget to set removeTriangles to NO originally so you can draw the triangles!
Hope this helps.