Remove UIView after animation without losing other elements - ios

What happens if I toggle between these two for hundreds of times? will be left handers of unused UIViews?
I have several controls on my main UIView and I want to animate (slide-up and slide-down) them as a group of controls, several times, then I decided to add them to an UIView and animate that view. But It seems every time when I add the view to the superView it remains there and if I run [view removeFromSuperView] it also remove all controls I've added to the view. Does it affect performance or can it cause memory leak problem?
(void)slideUp{
repeatViewTop = datePickerButton.frame.origin.y;
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, repeatViewTop)];
[view addSubview:taskTitle];
[view addSubview:taskNote];
[view addSubview:datePickerButton];
[view addSubview:taskSelectedDateViewer];
[self.view addSubview:view];
[UIView animateWithDuration:0.4f
delay:0.1f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
float tempY=view.frame.origin.y;
[view setCenter:CGPointMake(SCREEN_WIDTH/2,tempY)];
[view setAlpha:0.4f];
}
completion:^(BOOL finished){
}];
[self.view insertSubview:view atIndex:0];
}
This will slide down those controls:
- (void)slideDown{
taskTitle.userInteractionEnabled=NO;
//150=view.frame.origin.y after sliding up
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, -114, SCREEN_WIDTH, repeatViewTop)];
[view addSubview:taskTitle];
[view addSubview:taskNote];
[view addSubview:datePickerButton];
[view addSubview:taskSelectedDateViewer];
[self.view addSubview:view];
[UIView animateWithDuration:0.4f
delay:0.1f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
float tempY=view.frame.origin.y *(-1);
[view setCenter:CGPointMake(SCREEN_WIDTH/2,tempY)];
[view setAlpha:1.0f];
}
completion:^(BOOL finished){
}];
[self.view insertSubview:view atIndex:0];
}

You should add the elements in a View only once and keep reference to your view, then animate it and not insert it all the time.
You can create the view at any time, like in the viewDidLoad delegate, like this:
- (void)viewDidLoad {
//Other code here
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, repeatViewTop)];
view.tag = 1999;
[view addSubview:taskTitle];
[view addSubview:taskNote];
[view addSubview:datePickerButton];
[view addSubview:taskSelectedDateViewer];
[self.view addSubview:view];
}
then get a reference to the view in your animations like this:
(void)slideUp{
repeatViewTop = datePickerButton.frame.origin.y;
UIView *view = [self.view viewWithTag:1999];
[UIView animateWithDuration:0.4f
delay:0.1f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
float tempY=view.frame.origin.y;
[view setCenter:CGPointMake(SCREEN_WIDTH/2,tempY)];
[view setAlpha:0.4f];
}
completion:^(BOOL finished){
}];
}

Related

How to remove view from superview in run time?

Based on internet connectivity I have to remove or add subview to superview.
I can able to add subview in runtime. But not remove from subview.
I tried like this
if ([statusString isEqualToString:#"Access Not Available"]){
view = [[UIView alloc]initWithFrame:CGRectMake(0, navigationView.frame.size.height, self.view.frame.size.width, 50)];
[self.view addSubview:view];
view.backgroundColor = [UIColor lightGrayColor];
}else{
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
[view removeFromSuperview];
}];
}
But it is not removing from superview.
How can I do this?
///in view did load
view_NoConnectn = [[UIView alloc]init];
[view_NoConnectn setBackgroundColor:[UIColor whiteColor]];
[view_NoConnectn setFrame:CGRectMake(0, frameHeight, frameWidth, 35)];
UIWindow* mainWindow = [[UIApplication sharedApplication] keyWindow];
bool isFound=false;
for(UIView *child in [mainWindow subviews])
{
if([child tag]==007)
isFound=true;
}
if(!isFound)
{
[mainWindow addSubview: btn_setting];
}
[self.navigationController.view addSubview:view_NoConnectn];
////// whereever required
if (show){
if (self.navigationController.view.frame.size.height == frameHeight) {
[UIView animateWithDuration:1.0 animations:^{
[self.navigationController.view setFrame:CGRectMake(self.navigationController.view.frame.origin.x, self.navigationController.view.frame.origin.y, self.navigationController.view.frame.size.width, frameHeight - 35)];
[view_NoConnectn setFrame:CGRectMake(0, frameHeight-35, frameWidth, 35)];
[self.view layoutIfNeeded];
}];
}
}
else
{
if (self.navigationController.view.frame.size.height != frameHeight) {
[UIView animateWithDuration:1.0 animations:^{
[UIView animateWithDuration:0.8 animations:^{
[self.navigationController.view setFrame:CGRectMake(self.navigationController.view.frame.origin.x, self.navigationController.view.frame.origin.y, self.navigationController.view.frame.size.width, frameHeight)];
[view_NoConnectn setFrame:CGRectMake(0, frameHeight, frameWidth, 35)];
[self.view layoutIfNeeded];
}];
} completion:^(BOOL finished) {
[view_NoConnectn removeFromSuperview];
}];
}
}

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

UIView animation not work

I'd like to make settingView on myView display and disappear with animation.
I call -showSettingView
if (!self.settingView) : the animation correctly work.
But, else if (self.myView) : settingView disappear WITHOUT animation.
How do I fix it to make settingView disappear with animation?
#property (nonatomic, strong) UIView *myView;
#property (nonatomic, strong) UIView *settingView;
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem* settingButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:#selector(showSettingView)];
self.navigationItem.rightBarButtonItem = settingButton;
}
- (void)showSettingView
{
self.myView = [[UIView alloc]initWithFrame:CGRectMake(0, 568, 320, 480)];
self.myView.opaque = NO;
self.myView.backgroundColor = [UIColor colorWithWhite:1.0f alpha:0.0f];
[self.view addSubview:self.myView];
if (!self.settingView) {
self.settingView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 568)];
self.settingView.backgroundColor = [UIColor blackColor];
[self.myView addSubview:self.settingView];
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionTransitionFlipFromBottom
animations:^{self.myView.frame = CGRectMake(0, 60, 320, 480);}
completion:^(BOOL finished) {}
];
} else if (self.myView){
self.myView.frame = CGRectMake(0, 60, 320, 480);
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionCurveEaseIn
animations:^{self.myView.frame = CGRectMake(0, 568, 320, 480);}
completion:^(BOOL finished) {}
];
[self.settingView removeFromSuperview];
self.settingView = nil;
[self.myView removeFromSuperview];
}
}
Thank you.
You dealloc the settings view before the animation starts. Try this:
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionCurveEaseIn
animations:^{self.myView.frame = CGRectMake(0, 568, 320, 480);}
completion:^(BOOL finished) {
[self.settingView removeFromSuperview];
self.settingView = nil;
[self.myView removeFromSuperview];
}
];
*Also: If you are using auto layout you need to do one of these options:
A. Set the constrains of myView instead of the frame, before the block, and then call only layoutIfNeeded: inside the block.
B. Set the transform property in the animation block.
Try adding this line
[self layoutIfNeeded];
as the last line within your animation block. Something like that:
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionTransitionFlipFromBottom
animations:^{
self.myView.frame = CGRectMake(0, 60, 320, 480);
// any other stuff you have to move
[self layoutIfNeeded];
}
completion:^(BOOL finished) {}
];

ios Animation with [removeFromSuperview]

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];
}];

How to add subview with flip animation?

If you create a brand new single view app and put this code behind a button:
UIView *blah = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
blah.backgroundColor = [UIColor grayColor];
[UIView transitionWithView:blah duration:1
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[self.view addSubview:blah];
}
completion:^(BOOL finished){
}];
The subview is added immediately with no animation. If you add the subview first then try to animate it... you get the same problem.
UIView *blah = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
[self.view addSubview:blah];
[UIView transitionWithView:blah duration:1
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
blah.backgroundColor = [UIColor grayColor];
}
completion:^(BOOL finished){
}];
How on Earth do you animate a flip for a subview while or immediately after adding it?
You generally need to have the container that constrains the animation to be in place already:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect frame = CGRectMake(0, 0, 100, 100);
_container = [[UIView alloc] initWithFrame:frame];
_container.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:_container];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIView *subview = [[UIView alloc] initWithFrame:_container.bounds];
subview.backgroundColor = [UIColor darkGrayColor];
[UIView transitionWithView:_container
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[_container addSubview:subview];
}
completion:NULL];
}
This is worth a try:
UIView *blah = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
blah.backgroundColor = [UIColor grayColor];
[self.view addSubview:blah];
blah.alpha = 0.0; //Or with blah.hidden = TRUE and then FALSE inside the animation block
[UIView transitionWithView:blah
duration:1
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
blah.alpha = 1.0;
}
completion:^(BOOL finished){
}];

Resources