UIViewAnimateWithDuration completion never called - ios

I am using the UIView animateWithDuration:delay:options:animations:completion: method but the completion method is never getting called. Here is my code:
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^
{
//random lines of code
}completion:^(BOOL finished){
if (finished)
{
NSLog(#"FINISHED");
}
}];
EDIT: When I comment out the lines in my animations: it gets called???!!!
These are the lines:
CGFloat objectY = object.frame.origin.y;
objectY += speed;
object.frame = CGRectMake(object.frame.origin.x, objectY, 75, 75);

I am taking a guess - you want to animate the movement of a continuous gesture?
If yes, the animation never ends due the user interaction.
Just update the frame, no UIView Animation. Should work just fine.

Related

Bouncing animation while changing view frame

Add bouncing animation while changing UIVIew frame. I only know how to change frame but I don't know how to set bouncing effect while changing view frame. Below is my code....
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
CGRect frame = viewContent.frame;
frame.size.height = CGRectGetHeight(viewContentFullDetail);
viewContent.frame = frame;
} completion:^(BOOL finished) { }];
You can check animated gif image on below link. I want to add animation not same like this but near to this. Main animation are unfolding and bouncing effect.
https://drive.google.com/open?id=0B9k_Shyb5v62eFdxWXhYeXV3a0E
Please help. I don't know how to do this.
You need to try this
int duration, damping, velocity;
[UIView animateWithDuration:duration delay:0
usingSpringWithDamping:damping initialSpringVelocity:velocity
options:0 animations:^{
// your animation code here
} completion:nil];
Play with the damping and velocity values to know more about this feature in the animation code.
here is the link for a tutorial

How i can do an uiimageView zoom animation linked to uiscrollview contentoffest?

I'm trying to achive an animation that zoom an imageview accordingly to a scrollview offset (i have seen something similar in spotify and some others apps). How i can do? I have tried something like:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (Scroll.contentOffset.y<-10 && Scroll.contentOffset.y>-20) {
[UIView animateWithDuration:0.1
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
ImageView.transform=CGAffineTransformMakeScale(1.1, 1.1);
}
completion:^(BOOL finished){
}];
}
if (Scroll.contentOffset.y<-20 && Scroll.contentOffset.y>-30) {
[UIView animateWithDuration:0.1
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
ImageView.transform=CGAffineTransformMakeScale(1.2, 1.2);
}
completion:^(BOOL finished){
}];
}
}
and so on until a value of 1.6 . Naturally this methods doesn't works well, it is called to many times and visually it jitters... I wanto to achive this result:
The user scroll down the scrollview while an image view placed in the background is scaled until an arbitray value (and a reverse behaviour when the user returns to scroll up). What is a correct approch?
Try setting the transform depending on the contentOffset without using animations, like
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat scale = 1;
if(Scroll.contentOffset.y<0){
scale -= Scroll.contentOffset.y/10; //calculate the scale factor as you like
}
ImageView.transform = CGAffineTransformMakeScale(scale,scale);
}

how to pause uiview animation?

How to pause uiview animation and just leave it there?
//#define ANIMATION_WORM_OPTIONS (UIViewAnimationOptionCurveLinear|
// UIViewAnimationOptionBeginFromCurrentState)
- (IBAction)pressUp:(id)sender {
[self.game wormUp];
[self.gameScene.wormView.layer removeAllAnimations];
[UIView animateWithDuration:5 delay:0 options:ANIMATION_WORM_OPTIONS
animations:^{
[self.gameScene.wormView moveUp];
} completion:^(BOOL finished) {
}];
}
- (IBAction)pressRight:(id)sender {
[self.game wormRight];
[UIView animateWithDuration:5 delay:0 options:ANIMATION_WORM_OPTIONS
animations:^{
[self.gameScene.wormView moveRight];
} completion:^(BOOL finished) {
}];
}
For example here is what I am trying to do:
When I first tap "Right" a worm goes right.
Then when I tap "Up" during the worm goes right, the worm should stop and go up.
The problem in my code is the removeAllAnimations will first put the worm to the end of first animation end, then begin goes up.
You need to change the view's frame to the halting position frame. Just add the following before you do the removeAllAnimation on view.layer.
self.theView.frame = [self.theView.layer.presentationLayer frame];
CFTimeInterval pausedTime = [self.gameScene.wormView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
self.gameScene.wormView.layer.speed = 0.0;
self.gameScene.wormView.layer.timeOffset = pausedTime;

Is it posible to do multiple animations on UIView without using completion block

This is simple question just for illustrating point, my concrete code is much more complicated.
Let say that I have UILabel that is position on TOP LEFT.
With this code, I will move it to TOP RIGHT:
// labelMove is moved to TOP RIGHT
[UIView animateWithDuration:1.0f
delay:2.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^
{
labelMove.center = CGPointMake(250.0f, 40.0f);
}
completion:nil];
If I have this code:
// labelMove is moved to TOP RIGHT
[UIView animateWithDuration:1.0f
delay:2.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^
{
labelMove.center = CGPointMake(250.0f, 40.0f);
}
completion:nil];
// labelMove is moved to BOTTOM RIGHT
[UIView animateWithDuration:1.0f
delay:2.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^
{
labelMove.center = CGPointMake(250.0f, 450.0f);
}
completion:nil];
It will not start from TOP LEFT, but from TOP RIGHT, and then go BOTTOM RIGHT.
Somehow first animation is not animated, only the last one.
I do not get it why, but that is not so important.
I can put second in completion: block in first and then it will work.
Like this code.
// labelMove is moved to TOP RIGHT
[UIView animateWithDuration:1.0f
delay:2.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^
{
labelMove.center = CGPointMake(250.0f, 40.0f);
}
completion:^(BOOL finished){
// labelMove is moved to BOTTOM RIGHT
[UIView animateWithDuration:1.0f
delay:2.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^
{
labelMove.center = CGPointMake(250.0f, 450.0f);
}
completion:nil];
}];
QUESTION
Is it posible to have effect from last code but without using completion block in any way.
That is very important for me.
I try with CABasicAnimation, but could not do it, maybe somebody with more experience can ?
I am sure that there must be some way, but I just can not figure it out.
Your code with no completion block does not work because you are attempting to animate the label to two different locations at exactly the same point in time. This is physically impossible.
When you run that second animation inside a completion block, you are running it after the first animation, instead of at the same time. To achieve the same effect, dispatch the second animation so that it is performed after the first animation. Since the first animation will take 2.0 delay + 1.0 duration = 3.0 seconds to complete, dispatch after 3.0 seconds. See below.
// labelMove is moved to TOP RIGHT
[UIView animateWithDuration:1.0f
delay:2.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^
{
labelMove.center = CGPointMake(250.0f, 40.0f);
}
completion:nil];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// labelMove is moved to BOTTOM RIGHT
[UIView animateWithDuration:1.0f
delay:2.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^
{
labelMove.center = CGPointMake(250.0f, 450.0f);
}
completion:nil];
});
Just be aware that without using the completion block, you cannot insure the first animation is truly finished animating. In practice this should usually be fine.
You could use a CAKeyframeAnimation, and create a path using the two points.
Here are some examples from apple:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Animation_Types_Timing/Articles/PropertyAnimations.html

How to make UIView move by click?

I'm not sure whether I can describe it properly. It's a kind of UIView, and we see only it's part (with arrow,maybe. on the bottom of screen,maybe). User can click on it, and this view appears fullscreen(usually developer leaves there some additional information). How can I make it?
Try this:
-(void)show
{
[viewObj setFrame:CGRectMake(viewObj.frame.origin.x,viewObj.frame.origin.y,viewObj.frame.size.width, viewObj.frame.size.height)];//Here "viewObj.frame.origin.y" means 568
[UIView animateWithDuration:0.5 animations:^
{
[viewObj setFrame:CGRectMake(viewObj.frame.origin.x,0,viewObj.frame.size.width, viewObj.frame.size.height)];
}
completion:^(BOOL finished)
{
}];
}
-(void)hide
{
[viewObj setFrame:CGRectMake(viewObj.frame.origin.x,viewObj.frame.origin.y,viewObj.frame.size.width, viewObj.frame.size.height)];//Here "viewObj.frame.origin.y" means 0
[UIView animateWithDuration:0.5 animations:^
{
[viewObj setFrame:CGRectMake(viewObj.frame.origin.x,568,viewObj.frame.size.width, viewObj.frame.size.height)];
}
completion:^(BOOL finished)
{
}];
}
i just put the logic that just setting of view Y coordinate of That View and when user click on Button. that et animation and at the re setting the view frame with Y coordinate setting like:
yourview.frame = CGRectMake(0,280,320,568);
[UIView animateWithDuration:2
delay:0.1
options: UIViewAnimationOptionTransitionFlipFromBottom
animations:^{
yourview.frame = CGRectMake(0, 0, 320, 568);
}
completion:^(BOOL finished){
}];
Also see this example:
https://github.com/crocodella/PullableView
Here above github demo this same that you are looking for its output like:
Look at UIView reference:
https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html
Specifically:
#property(nonatomic) CGPoint center
And
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations
Example:
[UIView animateWithDuration:2.0 animations:^{
myView.center = CGPointMake(self.view.center.x, self.view.center.y + myOffset);
}];
Duration is in seconds. In this case, 2 seconds.
If you're using AutoLayout, you probably want to change the layout constant, rather then center property.
About Layout Constrains:
https://developer.apple.com/library/ios/documentation/AppKit/Reference/NSLayoutConstraint_Class/NSLayoutConstraint/NSLayoutConstraint.html
Look at constant property. You can also drag a constrain outlet from Interface Builder and access its constant. It's really simple once you get to know it a bit.

Resources