Is this animation possible in iOS, any third party API's for that?
Figured out myself with nested animations
-(void)viewDidLoad
{
expandiView = [[UIView alloc] initWithFrame:CGRectMake(137, 269, 30, 2
)];
expandiView.backgroundColor = [UIColor redColor];
[self.view addSubview:expandiView];
expandiView.hidden=YES;
}
-(IBAction)Expand:(id)sender {
expandiView.hidden=NO;
[UIView animateWithDuration:0.5f
animations:^{
expandiView.frame = CGRectMake(60, 269, 200, 2);
}
completion:^(BOOL finished) {
[UIView animateWithDuration:1
animations:^{
expandiView.frame = CGRectMake(60, 269, 200, 100);
}];
}];
}
-(IBAction)collapse:(id)sender {
[UIView animateWithDuration:0.5f
animations:^{
expandiView.frame = CGRectMake(60, 269, 200, 2);
}
completion:^(BOOL finished) {
[UIView animateWithDuration:0.5f animations:^{
expandiView.frame = CGRectMake(137, 269, 30, 2);
} completion:^(BOOL finished) {
expandiView.hidden=YES;
}];
}];
}
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 have a UIView which is initially hidden. I need to setHidden:NO (visible) with dropdown effect...
There's my simple code without effect
-(IBAction)btnAbrirDestaquesClick:(id)sender {
[self.viewDestaques setHidden:NO];
}
A simpler alternative to UIDynamicAnimator in iOS 7 is Spring Animation (a new and powerful UIView block animation), which can give you nice bouncing effect with damping and velocity:
[UIView animateWithDuration:duration
delay:delay
usingSpringWithDamping:damping
initialSpringVelocity:velocity
options:options animations:^{
//Animations
[self.viewDestaques setHidden:NO];
}
completion:^(BOOL finished) {
//Completion Block
}];
If you simply want to animate it try something like this:
[UIView animateWithDuration:.5 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.viewDestaques.frame = CGRectMake(0, 0, 320,30);
} completion:^(BOOL finished) {
[UIView animateWithDuration:.5 delay:2.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.viewDestaques.frame = CGRectMake(0, -30, 320,30);
} completion:^(BOOL finished) {
}];
}];
It worked for me:
-(IBAction)btnAbrirDestaquesClick:(id)sender {
[self.viewDestaques setTranslatesAutoresizingMaskIntoConstraints:YES]; //respeita o frame que eu setar, independentemente das constraints
[self.viewDestaques setFrame:CGRectMake(self.viewDestaques.frame.origin.x, self.viewDestaques.frame.origin.y, self.viewDestaques.frame.size.width, 0)];
[self.viewDestaques setHidden:NO];
while (self.viewDestaques.frame.size.height < self.frameViewDestaquesOriginal.size.height) {
[UIView animateWithDuration:2.0 animations:^{
[self.viewDestaques setFrame:CGRectMake(self.viewDestaques.frame.origin.x, self.viewDestaques.frame.origin.y, self.viewDestaques.frame.size.width, self.view.frame.size.height + 10)];
}completion: ^(BOOL completed){
}];
}
}
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!
I have three UIViews that i want to animate in a certain order (It is supposed to look like a news ticker with three different labels moving from above then display and then move all the way to the outside of the view). Now this whole process is supposed to repeat infinitely.
This is the code i used:
[UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^
{
[morningPrayerView setFrame:CGRectMake(0, 0, 320, 30)];
[morningPrayerView setAlpha:1.f];
}
completion:^(BOOL finished)
{
[UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^{
[morningPrayerView setFrame:CGRectMake(0, 30, 320, 30)];
[morningPrayerView setAlpha:1.f];
} completion:^(BOOL finished) {
{
[UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^{
[middayPrayerView setFrame:CGRectMake(0, 0, 320, 30)];
[middayPrayerView setAlpha:1.f];
} completion:^(BOOL finished) {
{
[UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^{
[middayPrayerView setFrame:CGRectMake(0, 30, 320, 30)];
[middayPrayerView setAlpha:1.f];
} completion:^(BOOL finished) {
{
[UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^{
[eveningPrayerView setFrame:CGRectMake(0, 0, 320, 30)];
[eveningPrayerView setAlpha:1.f];
} completion:^(BOOL finished) {
{
[UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveLinear animations:^{
[eveningPrayerView setFrame:CGRectMake(0, 30, 320, 30)];
[eveningPrayerView setAlpha:1.f];
} completion:^(BOOL finished) {
//this block is called when the animation is over
}];
} }];
} }];
} }];
} }];
}];
The problem is that only the first animation gets the go and none of the other animations start.
IMHO the UIViewAnimationOptionRepeat switch means to repeat the animation indefinitely, therefore your first animation loops forever and never calls the completion handler. Simply wrap the whole animation setup in method, remove the repeat switches and when the last completion handler is executed, call the method again to repeat the whole show? Something like this:
- (void) animateView {
[UIView animateWithDuration:5.0 animations:^{
// …
} completion:^(BOOL finished) {
[self animateView];
}];
}
That’s probably a retain cycle, but as long as you cancel the animation eventually, it should be OK.
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) {
}];
}];
}];