ios Animation with [removeFromSuperview] - ios

I use the following lines of code:
[UIView animateWithDuration:0.50
animations:^{ itemView.transform = CGAffineTransformIdentity; }
completion:^(BOOL finished) { if (finished) [itemView removeFromSuperview]; }];
The animation does nothing. If I take the removeFromSuperview out of the completion block, it doesn't work either, I guess because the view is removed before it completes. So, either way, the appearance is the same - no animation.
I'll appreciate any suggestion or workaround on this.

Are you setting the transform correctly? The below is an example of scaling a UIView to zero area and then removing it from the superview.
UIView *itemView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 200, 200)];
[itemView setBackgroundColor:[UIColor redColor]];
[self.view addSubview:itemView];
CGAffineTransform trans = CGAffineTransformScale(self.view.transform, 0, 0);
[UIView animateWithDuration:2.5 delay:0 options:0 animations:^{
itemView.transform = trans;
} completion:^(BOOL finished) {
[itemView removeFromSuperview];
}];

Related

How to give image Animations to multiple images at Different Locations in a UIView?

How to give 'image' Animations to multiple images at Different
Locations in a 'UIView'?
1) I had 3 images.
2) i want to Add these 3 Images at 3 different locations animatedly, means add one by one images animatedly with some duration??
How can I achieve this?
As per your requirement you want to animate image one by one
for that purpose use completion block of first image animation to animate second image and so on like below code
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"-t%d",1]]];
[imgView setBackgroundColor:[UIColor redColor]];
UIImageView *imgView2 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"-t%d",2]]];
[imgView2 setBackgroundColor:[UIColor redColor]];
UIImageView *imgView3 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"-t%d",2]]];
[imgView3 setBackgroundColor:[UIColor redColor]];
[self.view addSubview:imgView];
[self.view addSubview:imgView2];
[self.view addSubview:imgView3];
[UIView animateWithDuration:0.5 delay:1.0 options:UIViewAnimationOptionLayoutSubviews animations:^{
[imgView setFrame:CGRectMake(0, 0, 150, 150)];
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.5 delay:1.0 options:UIViewAnimationOptionLayoutSubviews animations:^{
[imgView2 setFrame:CGRectMake(self.view.frame.size.width - 150, 0, 150, 150)];
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.5 delay:1.0 options:UIViewAnimationOptionLayoutSubviews animations:^{
[imgView3 setFrame:CGRectMake(0, self.view.frame.size.height - 150, 150, 150)];
} completion:^(BOOL finished) {
}];
}];
}];
It will Help you :)
Lets say 3 views are _redView, _greenView and _blueView check out following method to move those from one to another location. I have used random location you can give specific if you want. Here you can have working example of it just select ViewAnimationsTest project of the work space and run.
- (int) randomFloatingGenerator : (int) max{
return arc4random() % max;
}
- (void) animate3Views {
[UIView animateWithDuration:2.0
animations:^{
_redView.transform = CGAffineTransformMakeTranslation([self randomFloatingGenerator : 270], [self randomFloatingGenerator:480]);
_greenView.transform = CGAffineTransformMakeTranslation([self randomFloatingGenerator : 270], [self randomFloatingGenerator:480]);
_blueView.transform = CGAffineTransformMakeTranslation([self randomFloatingGenerator : 270], [self randomFloatingGenerator:480]);
} completion:^(BOOL finished) {
[self animate3Views];//if don;t want continuous translation remove this line
}];
}
Probably the easiest way to do this is to use 3 animations called with delay.
for (NSInteger i = 0; i < 3; i++) {
UIView *view = myViews[i];
CGRect frame = [self frameForViewAtIndex: i];
NSTimeInterval duration = 0.5;
NSTimeInterval delay = i * 0.5;
[UIView animateWithDuration: duration delay: delay options: 0 animations: ^{
view.frame = frame;
} completion: nil];
}
Where myViews is array of views to be animated, frameForViewAtIndex: is the method that returns frame for corresponding view.

Replace subview with another, animating size change

I have a container view that has one subview. I want to replace this subview with another view which has a different size than original, so the container should be resized as well. Here's what I'm trying to do
UIView *content = NEW_CONTENT;
content.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentContainer layoutIfNeeded]; // the container view
// make the old content disappear first
[UIView animateWithDuration:0.3
animations:^{
UIView *oldContent = [self.contentContainer.subviews firstObject];
oldContent.alpha = 0.0f;
}
completion:^(BOOL finished) {
// then replace it with a new content
[UIView transitionWithView:self.contentContainer
duration:0.1
options:0
animations:^{
[[self.contentContainer.subviews firstObject] removeFromSuperview];
[self.contentContainer addSubview:content];
[content autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero];
[self.contentContainer layoutIfNeeded];
}
completion:^(BOOL finished) { // completion stuff}];
}];
Old content opacity animates properly, but the layout is changed without any animation. How could I fix it?
//3 views(container,first,second) allocate in viewdidload
UIView *container=[[UIView alloc] initWithFrame:CGRectMake(20, 20, 250, 300)];
container.backgroundColor=[UIColor redColor];
[self.view addSubview: container];
UIView *first=[[UIView alloc] initWithFrame:CGRectMake(100, 50, 100, 100)];
first.backgroundColor=[UIColor blueColor];
[self.view addSubview: first];
UIView *second=[[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 150)];
second.backgroundColor=[UIColor purpleColor];
second.alpha=0;
[self.view addSubview: second];
//Animation Function with first view removed adn changing the frame of container and adding the second view
[UIView transitionWithView:first duration:1.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
first.alpha=0.0;
} completion:^(BOOL finished) {
[UIView transitionWithView:second duration:1.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
container.frame=CGRectMake(50, 10, 100, 200);
second.alpha=1.0;
} completion:^(BOOL finished) {
}];
}];
I think so u r trying this same scenario.it works perfectly in my case

Animating a UIView to slide down, then slide up

Im trying to figure out why this isnt working
in my tableViewcontroller viewDidLoad
self.headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 5, 320,0)];
self.headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 5, 320, 0)];
self.headerLabel.textAlignment = NSTextAlignmentCenter;
self.headerLabel.text = #"text";
[self.view addSubview:self.headerView];
[self.headerView addSubview:self.headerLabel];
[UIView animateWithDuration:.5 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.headerLabel.frame = CGRectMake(0, 5, 320,15);
self.headerView.frame = CGRectMake(0, 5, 320,15);
} completion:^(BOOL finished) {
[UIView animateWithDuration:.5 delay:2.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.headerLabel.frame = CGRectMake(0, 5, 320,0);
self.headerView.frame = CGRectMake(0, 5, 320,0);
} completion:^(BOOL finished) {
}];
}];
if I remove the slide back up part in the completion block of the first animate call It works. The view slides down correctly. However I cannot get it
to shrink back up at all. When I include the slide up code in the completion block the view is not displayed at all on load and I dont know why and Im going insane
I'm not sure why the label disappears, but you can fix that by giving the view and label an appropriate height when you create them, and only animate the label's y position rather than its height.
- (void)viewDidLoad {
[super viewDidLoad];
self.headerView = [[UIView alloc] initWithFrame:CGRectMake(0, -30, 320,30)];
self.headerView.backgroundColor = [UIColor yellowColor];
self.headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 5, 320, 21)];
self.headerLabel.textAlignment = NSTextAlignmentCenter;
self.headerLabel.text = #"text";
[self.view addSubview:self.headerView];
[self.headerView addSubview:self.headerLabel];
[UIView animateWithDuration:.5 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.headerView.frame = CGRectMake(0, 0, 320,30);
} completion:^(BOOL finished) {
[UIView animateWithDuration:.5 delay:2.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.headerView.frame = CGRectMake(0, -30, 320,30);
} completion:^(BOOL finished) {
}];
}];
}
viewDidLoad is not really the best place to be starting animations. You should move the code to viewWillAppear: , and if you only want this to occur the first time the view appears, you should add a BOOL property to your controller (i.e. self.hasperformedInitialHeaderAnimation), so:
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
if(!self.hasPerformedInitialHeaderAnimation){
self.hasPerformedInitalHeaderAnimation = YES;
[UIView animateWithDuration:.5 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.headerLabel.frame = CGRectMake(0, 5, 320,15);
self.headerView.frame = CGRectMake(0, 5, 320,15);
} completion:^(BOOL finished) {
[UIView animateWithDuration:.5 delay:2.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.headerLabel.frame = CGRectMake(0, 5, 320,0);
self.headerView.frame = CGRectMake(0, 5, 320,0);
} completion:^(BOOL finished) {
}];
}

Creating a custom view with an animation

Im trying to make a custom view where one of it's elements(a UILabel) has animation that when a button of the custom view is tapped the label should expand and then contract. The first part of the animation happens correctly but not the second. Im using this method.
[UIView animateWithDuration:1.3 animations:^{
CGRect frame = CGRectMake(50, 15, 140, 20);
[labelFav setFrame:frame];
} completion:^(BOOL finished) {
//[labelFav setHidden:YES];
[UIView animateWithDuration:1.3 animations:^{
CGRect frame = CGRectMake(50, 15, 0, 20);
[labelFav setFrame:frame];
}];
}];
I believe it's a problem with how the methods Refresh and LayoutSubviews are implemented.
I did it following this tutorial, ray wenderlinch
The problem comes when after the first animation is called, LayoutSubviews is called, so all the items are set to the initial position, and when the first animation is finished the second one starts but the items are set to the original state, so I believe the animation doesnt happen because there's been a change between animations.
I would like to know how to implement this correctly, can you lend me a hand?
Thanks.
PS: This is a second question about the same problem but with a different angle.my previous question
[UPDATE]
This is my code for LayoutSubviews:
- (void)layoutSubviews {
[super layoutSubviews];
if(_idEvent == 0) return;
_buttonFav = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 40, 40)];
[_buttonFav setImage:[UIImage imageNamed:#"fav.png"] forState:UIControlStateNormal];
[_buttonFav addTarget:self action:#selector(pressedFavButton:) forControlEvents:UIControlEventTouchDown];
_labelButton = [[UILabel alloc]initWithFrame:CGRectMake(0, 45, 0, 20)];
_labelButton.text = #"LABEL";
[self addSubview:_labelButton];
[self addSubview:_buttonFav];
}
Which is called right before the second animation. My refresh method is:
- (void)refresh {
if(selected){
[_buttonFav setImage:[UIImage imageNamed:#"fav_sel.png"] forState:UIControlStateNormal];
}
else{
[_buttonFav setImage:[UIImage imageNamed:#"fav.png"] forState:UIControlStateNormal];
}
}
Where I just set the image for the button depending on an attribute that lets me know if the button was tapped.
I do, how to make an animation with Auto-layout then? With the new
XCode you dont have an a option to disable it.
Add a width constraint to a label. Then create IBOutlet to this constraint in your implementation file (see the section 3. here, if you don't know how to do that), let's say something like:
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *buttonWidthConstraint;
Then you can animate it this way:
[UIView animateWithDuration:1.3 animations:^{
self.buttonWidthConstraint.constant = 140;
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.3 animations:^{
self.buttonWidthConstraint.constant = 0;
[self.view layoutIfNeeded];
}];
}];
use SetTransform and CGAffineTransform
try this out
[UIView animateWithDuration:1.3 animations:^{
[labelFav setTransform:CGAffineTransformMakeScale(0.5,0.5)];
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.3 animations:^{
[labelFav setTransform:CGAffineTransformMakeScale(1.0,1.0)];
}];
}];
Try to encapsulate the UILabel into a UIView and animate that view.
UIView *auxView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)];
[auxView addSubview:labelFav];
[UIView animateWithDuration:1.3 animations:^{
CGRect frame = CGRectMake(50, 15, 140, 20);
[auxView setFrame:frame];
} completion:^(BOOL finished) {
//[labelFav setHidden:YES];
[UIView animateWithDuration:1.3 animations:^{
CGRect frame = CGRectMake(50, 15, 10, 20);
[auxView setFrame:frame];
}];
}];

How to remove SubView with slide in iOS?

I tried to add SubView with animation following codes.It's okay.
[self.view addSubview:pickerView];
pickerView.frame = CGRectMake(0, 0, 320, 50);
[UIView animateWithDuration:1.0
animations:^{
pickerView.frame = CGRectMake(0, 152, 320, 260);
}];
And i also want to remove the subView with slide animation like above animation.
How can i do that?
Thanks in advance.
you could use this animateWithDuration completion block to remove the view
[UIView animateWithDuration:1.0
animations:^{
pickerView.frame = //move it out of screen
} completion:^(BOOL finished) {
[pickerView removeFromSuperView];
}];
[UIView animateWithDuration:.2 animations:^{
pickerView.frame = CGRectMake(0, 0, 320, 50);
} completion:^(BOOL finished){
[pickerView removeFromSuperView];
}];

Resources