I created this animation and I entered through the stop animation
[UIView setAnimationDidStopSelector:#selector (TermineAnimazioneGoPointAssignedWithDelay)] ;
When the animation part of the SetAnimationDidStop is not called ... Can you tell me why and where am I doing wrong ?
This is all the way animation :
-(void)setViewStatusGoPointassigned {
ViewgoPointAssignMessage = [[UIView alloc] initWithFrame:CGRectMake(115, 150, 100, 100) ];
ViewgoPointAssignMessage.backgroundColor = [UIColor colorWithRed:(77/255.0) green:(108/255.0) blue:(143/255.0) alpha:(1)];
[ViewgoPointAssignMessage.layer setCornerRadius:10.0f];
[ViewgoPointAssignMessage.layer setMasksToBounds:YES];
[UIView animateWithDuration:0.2 animations:^{
ViewgoPointAssignMessage.transform = CGAffineTransformMakeScale(1.05, 1.05);
ViewgoPointAssignMessage.alpha = 0.8; }
completion:^(BOOL finished){
[UIView animateWithDuration:2/15.0 animations:^{
ViewgoPointAssignMessage.transform = CGAffineTransformMakeScale(0.9, 0.9);
ViewgoPointAssignMessage.alpha = 0.9; }
completion:^(BOOL finished) {
[UIView animateWithDuration:1/7.5 animations:^{
ViewgoPointAssignMessage.transform = CGAffineTransformIdentity;
ViewgoPointAssignMessage.alpha = 1.0; } ];
} ];
} ];
[self.view addSubview:ViewgoPointAssignMessage];
[UIView setAnimationDidStopSelector:#selector(TermineAnimazioneGoPointAssignedWithDelay)];
}
-(void)TermineAnimazioneGoPointAssignedWithDelay {
[self performSelector:#selector(EliminazioneViewAfterDelay) withObject:self afterDelay:0.01];
}
-(void)EliminazioneViewAfterDelay {
CGRect endREct;
endREct = CGRectMake(350 , 0 , 330, 90);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.005];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(EliminaAnimazione)];
ViewgoPointAssignMessage.frame = endREct;
[UIView commitAnimations];
}
- (void)EliminaAnimazione {
[ViewgoPointAssignMessage removeFromSuperview];
}
First of all, to answer your question.
You may try
[UIView animateWithDuration:(NSTimeInterval)duration animations:^(void)animations completion:^(BOOL finished)completion]
and call [self TermineAnimazioneGoPointAssignedWithDelay] in the completion.
Secondly, [UIView setAnimationDidStopSelector:#selector(TermineAnimazioneGoPointAssignedWithDelay)] doesn't work because according to the reference, setAnimationDidStopSelector must be called between calls to the beginAnimations:context: and commitAnimations methods. Since your code doesn't comply to this rule, the function does not work either.
Hopefully it explains! Good Luck!
Related
I'm having some issues with my animations. The intended result is that the UIButton's should both move to their positions, and once they reach their positions they must oscillate upwards and downwards, subtly, to simulate reaching the end of their bungee chord, if you will. The result I'm achieving is that every animation apart from the oscillation is executing perfectly. Why is this? (The oscillation animation I refer to is, of course, the spring animateWithDuration method.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
_orText.alpha = 0;
//Email login button properties
_emailLoginForwardButton.layer.cornerRadius = _emailLoginForwardButton.frame.size.width / 2;
self.emailLoginForwardButton.layer.borderWidth = 1.5f;
self.emailLoginForwardButton.layer.borderColor = [UIColor whiteColor].CGColor;
[self.emailLoginForwardButton setImageEdgeInsets:UIEdgeInsetsMake(7, 7, 7, 7)];
_emailLoginForwardButton.frame = CGRectMake(77, 700, 40, 40);
[UIView animateWithDuration:0.5
animations:^
{
_emailLoginForwardButton.frame = CGRectMake(77, 470, 40, 40);
}
completion:^(BOOL finished)
{
[UIView animateWithDuration:0.3
delay:0.6
usingSpringWithDamping:0.2
initialSpringVelocity:0.4
options:0
animations:^(void){}
completion:^(BOOL finished)
{
_orText.text = #"or";
[UIView animateWithDuration:0.4
animations:^
{
[_orText setAlpha:1];
}
];
}
];
}
];
//Google login button properties
_googleLoginForwardButton.layer.cornerRadius =_googleLoginForwardButton.frame.size.width / 2;
self.googleLoginForwardButton.layer.borderWidth = 1.5f;
self.googleLoginForwardButton.layer.borderColor = [UIColor grayColor].CGColor;
_googleLoginForwardButton.frame = CGRectMake(257, 700, 40, 40);
[UIView animateWithDuration:0.5
delay:0.4
options:0
animations:^
{
_googleLoginForwardButton.frame = CGRectMake(257, 470, 40, 40);
}
completion:^(BOOL finished)
{
[UIView animateWithDuration:0.3
delay:0.3
usingSpringWithDamping:0.2
initialSpringVelocity:0.4
options:0
animations:^
{
}
completion:^(BOOL finished)
{
}
];
}
];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.googleLoginForwardButtonBottomConstraints.constant = -100.0;//e.g
self.emailLoginForwardButtonBottomConstraints.constant = -100.0;//e.g
[UIView animateWithDuration:0.6
delay:0.6
usingSpringWithDamping:0.2
initialSpringVelocity:0.4
options:0
animations:^(void){
self.googleLoginForwardButtonBottomConstraints.constant = 40.0;//e.g
self.emailLoginForwardButtonBottomConstraints.constant = 40.0;//e.g
[self.view layoutIfNeeded];
}
completion:^(BOOL finished) {
}];
}
I have run this code and its working. Hope it will help you.
[UIView animateWithDuration:1
delay:0.6
usingSpringWithDamping:0.42
initialSpringVelocity:0.1
options:0
animations:^(void)
{
_orText.text = #"or";
[UIView animateWithDuration:0.7
animations:^
{
[_orText setAlpha:1];
}];
[UIView animateWithDuration:0.6
animations:^
{
_emailLoginForwardButton.frame = CGRectMake(77, 470, 40, 40);
}];
[UIView animateWithDuration:0.6
animations:^
{
_googleLoginForwardButton.frame = CGRectMake(257, 470, 40, 40);
}
];
[self.view layoutIfNeeded];
}
completion:^(BOOL finished) {
}];
This was my solution, however there was more I wanted to do with this code. I wanted to make both buttons move at different intervals, and an if statement won't work here, for some reason. Also, I only wanted this to initialise when another action has taken place, which is still possible to do, but I'd prefer to be able to make them move at different times.
I am attempting to make my item "glow" every 3 seconds changing its alpha from a high to low value and back. It however "flickers" and basically changes every 0.2 seconds from color to color randomly. I have pasted the method below. Its probably something to do with when completion is called but not sure?
-(void)showLoading{
[self.postTableView setHidden:YES];
self.isLoading = true;
//Disappear
[UIView animateWithDuration:1.5 animations:^(void) {
self.loadingLabel.alpha = 0.8;
self.loadingLabel.alpha = 0.3;
}
completion:^(BOOL finished){
//Appear
[UIView animateWithDuration:1.5 animations:^(void) {
self.loadingLabel.alpha = 0.3;
self.loadingLabel.alpha = 0.8;
}completion:^(BOOL finished2){
if(true){
[self showLoading];
}
}];
}]; }
self.loadingLabel.alpha = .8;
[UIView animateWithDuration:1.5 delay:0 options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat animations:^{
self.loadingLabel.alpha = .3;
} completion:nil];
UIViewAnimationOptionAutoreverse & UIViewAnimationOptionRepeat can help you.
you can stop it by
self.loadingLabel.alpha = .8;
or the other animation.
[UIView animateWithDuration:1.5 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.loadingLabel.alpha = .8;
} completion:nil];
UIViewAnimationOptionBeginFromCurrentState is a useful option for you to stop your animation by the other animation.
-(void)viewDidLoad{
//use schedule timer to call repeatedly showLoading method until loading done
}
-(void)showLoading{
[self.postTableView setHidden:YES];
self.isLoading = true;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
self.loadingLabel.alpha = 0.3;
[UIView commitAnimations];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
self.loadingLabel.alpha = 0.8;
[UIView commitAnimations];
}
I created a UIView Animation, my array contains 10 images. I want to move one place to another place when button is pressed. Below code is working but problem is all 10 images is moving.
-(IBAction)moveImageAtIndex:(int)index {
UIButton *buttonCelebrate = [redAppleArray objectAtIndex:j];
UIButton *buttonRefer = [reffButtonArray objectAtIndex:j];
currentView = buttonCelebrate;
CGRect frame = currentView.frame;
CGRect frame1 = buttonRefer.frame;
frame.origin.x = frame1.origin.x;
frame.origin.y = frame1.origin.y;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration: 2.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
currentView.frame = frame;
[UIView animateWithDuration:2.0 animations:^
{
[currentView setTransform:CGAffineTransformIdentity];
}completion:^(BOOL finished) {
if (finished) {
if(index != [redAppleArray count] - 1) {
[self moveImageAtIndex:index+1];
}
}
}];
[UIView commitAnimations];
}
Expected Output is: I want to move one by one instead of all.
screenshot
You have to wait until the current animation has finished, then you can start the next animation. A simple solution is to use recursion:
-(void)moveImageAtIndex:(int)index {
[UIView animateWithDuration:2.0 animations:^{
//Do animation
}completion:^(BOOL finished) {
if (finished) {
if(index != [redAppleArray count] - 1) {
[self moveImageAtIndex:index + 1];
}
}
}];
}
Remove the code from loop and keep in the method which is called by button then by pressing the button your images in array will be moved one by one according to user clicks.
declare i as int in the .h file and make i value as 0 in viewDidLoad and Don't forget to increment the i value in the end
use below code
-(void)viewDidLoad {
i=0;
[super viewDidLoad];
}
-(IBAction)methodName:(id)sender {
UIButton *buttonCelebrate = [redAppleArray objectAtIndex:index];
currentView = buttonCelebrate;
CGRect frame = currentView.frame;
CGRect frame1 = reffButton.frame;
frame.origin.x = frame1.origin.x;
frame.origin.y = frame1.origin.y;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration: 2.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
currentView.frame = frame;
[UIView animateWithDuration:2.0 animations:^
{
[currentView setTransform:CGAffineTransformIdentity];
}completion:^(BOOL finished) {
if (finished) {
}
}];
[UIView commitAnimations];
i++;
}
as per the Eric use below code
You have to wait until the current animation has finished, then you can start the next animation. A simple solution is to use recursion:
-(void)moveImageAtIndex:(int)index {
[UIView animateWithDuration:2.0 animations:^{
UIButton *buttonCelebrate = [redAppleArray objectAtIndex:i];
currentView = buttonCelebrate;
CGRect frame = currentView.frame;
CGRect frame1 = reffButton.frame;
frame.origin.x = frame1.origin.x;
frame.origin.y = frame1.origin.y;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration: 2.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
currentView.frame = frame;
[UIView animateWithDuration:2.0 animations:^
{
[currentView setTransform:CGAffineTransformIdentity];
}completion:^(BOOL finished) {
if (finished) {
if(index != [redAppleArray count] - 1) {
[self moveImageAtIndex:index + 1];
}
}
}];
[UIView commitAnimations];
}
The new solution is:
-(void)moveImageStartAtIndex:(int)index withHowMany:(int)howMany{
[UIView animateWithDuration:2.0 animations:^{
//Do animation
}completion:^(BOOL finished) {
if (finished) {
if(howMany > 1) {
[self moveImageStartAtIndex:index + 1 withHowMany:howMany - 1];
}
}
}];
}
I have a 8 imagaviews that I have added to my view with size (0,0). Now what I want to do is to pull op each imageView after each other with a UIViewanimation. I want to do 2 animations. First the size should go to from (0,0) --> (105,85) and after that is finished the imageview size should go from (105,85) --> (93,75)
Now I have a method where I first place all my imageViews on the correct place.All the images have size (0,0) At the end I call the method startAnimating
-(void)startAnimating{
[self animageButton:[arrButtons objectAtIndex:0]];
}
Then the first view animation ( from (0,0) --> (105,85) )
-(void)animageButton:(UIImageView *)imgButton{
loopIndex++;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0];
[UIView setAnimationDelegate:self];
CGRect btnFrame = imgButton.frame;
btnFrame.size.width = 105;
btnFrame.size.height = 85;
[UIView transitionWithView:self.view
duration:0.5f
options:UIViewAnimationOptionCurveEaseIn
animations:^{
imgButton.frame = btnFrame;
}
completion:nil];
[UIView commitAnimations];
[self animageButton2:imgButton];
}
this calls the second method (from (105,85) --> (93,75))
-(void)animageButton2:(UIImageView *)imgButton{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector: #selector(animationDidStop:finished:context:)];
CGRect btnFrame2 = imgButton.frame;
btnFrame2.size.width = 93;
btnFrame2.size.height = 75;
[UIView transitionWithView:self.view
duration:0.5f
options:UIViewAnimationOptionCurveEaseIn
animations:^{
imgButton.frame = btnFrame2;
}
completion:nil];
[UIView commitAnimations];
}
Now at this point the first imageView should be animated. Now when the animation has finished. I to this.
-(void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
//do smth
if(loopIndex <= 7){
NSLog(#"called");
UIImageView *imgObj = [arrButtons objectAtIndex:loopIndex];
[self animageButton:imgObj];
}else{
NSLog(#"done");
return;
}
}
What it is doing at the moment it is animating all the images at the same time. But I want that the next imageview starts animating when the previous has done.
Can anyone help me with this ?
-(void)startAnimating
{
NSTimeInterval delay = 0.0;
for(UIImageView *imageView in arrButtons)
{
[self performSelector:#selector(animageButton:) withObject:imageView afterDelay:delay];
delay +=1.0;
}
}
-(void)animageButton:(UIImageView *)imgButton{
CGRect btnFrame = imgButton.frame;
btnFrame.size.width = 105;
btnFrame.size.height = 85;
[UIView animateWithDuration:0.5f animations:^{
imgButton.frame = btnFrame;
} completion:^(BOOL finished) {
[self animageButton2:imgButton];
}];
}
-(void)animageButton2:(UIImageView *)imgButton
{
CGRect btnFrame2 = imgButton.frame;
btnFrame2.size.width = 93;
btnFrame2.size.height = 75;
[UIView animateWithDuration:0.5f animations:^{
imgButton.frame = btnFrame2;
} completion:^(BOOL finished) {
}];
}
I have not tested the code. Let me know if there are any issues. Thanks.
How do we go about animating the UILabel's width so that it increases and decreases in width only using UIView animateWithDuration
Thank you for your help (at this point i'm so frustrated as I've been trying to do so but it does not work)
You can set the frame of the UILabel inside the UIView animation block. Something like this:
CGRect originalFrame = self.address.frame;
[UIView animateWithDuration:0.3
animations:^{
self.myLabel.frame = CGRectMake(0, 0, 100, 100);
}
completion:^(BOOL finished) {
// use similar UIView animation to resize back to original
}];
Obviously the dimensions you feed in will depend on your app, and may be calculated based on the content.
try to increase and decrease the frame width with an animation as below
// original label frame CGRectMake( 0,0, 100,60 );
[UIView beginAnimations: #"moveLogo" context: nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:1.0];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationRepeatCount:4];
//increasing frame width
label.frame = CGRectMake( 0,0, 400,60 );
[UIView commitAnimations];
finally did it like this with blocks in iOS 5.0
[UIView animateWithDuration:2. delay:0 options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionBeginFromCurrentState animations:^{
[self.messageLabel setFrame:CGRectMake(90, 0, labelSize.width, 90)];
} completion:^(BOOL finished) {
}];
Try this
[UIView animateWithDuration:0.6 animations:^(void)
{
self.label.bounds = CGRectMake(100, 100, 200, 100);
}completion:^(BOOL finished) {
[UIView animateWithDuration:0.6 animations:^(void)
{
self.label.bounds = CGRectMake(100, 100, 100, 100);
}];
}];
I was able to do it in this way. self refers to the view in which i'm adding the label. in the init, add the label with width as 1 px. then use the below.. the UIViewAnimationOptionBeginFromCurrentState allows it to be opened like a door PHEW!
[UIView animateWithDuration:1. delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
[self setFrame:CGRectMake(self.frame.origin.x-labelSize.width-PADDING, self.frame.origin.y, self.frame.size.width+labelSize.width+PADDING, self.frame.size.height)];
[self.messageLabel setFrame:CGRectMake(95, 10, labelSize.width, labelSize.height)];
self.messageLabel.alpha = 1;
} completion:^(BOOL finished) {
[UIView animateWithDuration:1. delay:2. options:0 animations:^{
self.messageLabel.alpha = 0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:1. delay:0. options:0 animations:^{
[self setFrame:CGRectMake(self.frame.origin.x+labelSize.width+PADDING, self.frame.origin.y, self.frame.size.width-labelSize.width-PADDING, self.frame.size.height)];
} completion:^(BOOL finished) {
}];
}];
}];