TableView not animating - ios

I want to animate UIView simultaneously. But my UIView is not animated. Side over lap But my UITableView is not animated.
[self.view addSubview:sideview];
[sidevieww setHidden:NO];
[UIView animateWithDuration:0.3 animations:^{
[sidevieww setFrame:CGRectMake(0, 0, sidevieww.frame.size.width, sidevieww.frame.size.height)];
[mytable setFrame:CGRectMake(240,mytable.frame.origin.y,mytable.frame.size.width,mytable.frame.size.height)];
[mynav setFrame:CGRectMake(240,mynav.frame.origin.y,mynav.frame.size.width,mynav.frame.size.height)];
[mybutton setFrame:CGRectMake(240, mybutton.frame.origin.y, mybutton.frame.size.width, mybutton.frame.size.height)];
} completion:^(BOOL finished) {
sideview =true;
}];

That is really not the best way to configure frame.
Replace your code by this one:
[self.view addsubview:sideview];
[sidevieww setHidden:NO];
CGRect frameSideVieww = sidevieww.frame;
frameSideVieww.origin.x = frameSideVieww.origin.y = 0;
CGRect frameMyTable = mytable.frame;
frameMyTable.origin.x = 240;
CGRect frameMyNav = mynav.frame;
frameMyNav.origin.x = 240;
CGRect frameMyButton = mybutton.frame;
mybutton.origin.x = 240;
[UIView animateWithDuration:0.3 animations:^{
[sidevieww setFrame:frameSideVieww];
[mytable setFrame:frameMyTable];
[mynav setFrame:frameMyNav];
[mybutton setFrame:frameMyButton];
}completion:^(BOOL finished) {
sideview =true;
}];
Also, check if your class is subclass of UIViewController.

Related

How to animate constraints one by one in IOS?

I have 6 views. I want to animate the constraints one by one, ie, i need the animation on second view only after first, then after second the third and so on. I have added the code in the completion handler of the animations, but it is not working. initial value of all the constraint is set to 300 in storyboard. I want to change it to 0 one by one. Now, only the first animation is working. This is what i have done.
layoutTopFirst.constant = 0.0;
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
self->layoutTopSecond.constant = 0.0;
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
self->layoutTopThird.constant = 0.0;
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
self->layoutTopFourth.constant = 0.0;
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
self->layoutTopFifth.constant = 0.0;
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
self->layoutTopSixth.constant = 0.0;
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
}];
}];
}];
}];
}];
}];
How to do animations one after another?
If only the first one is animating, make sure that
your other five constraint references all point to different vertical constraints ... if they were nil for example, you won't see any changes;
that they're all isActive;
that there aren't any other constraints that are preventing the updated constants from yielding changes.
For what it's worth, you might consider eliminating your tower of completion handlers with keyframe animation, e.g.
CGFloat relativeDuration = 1.0 / 6.0;
[UIView animateKeyframesWithDuration:6 delay:0 options:kNilOptions animations:^{
[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:relativeDuration animations:^{
self.topConstraint1.constant = 0;
[self.view layoutIfNeeded];
}];
[UIView addKeyframeWithRelativeStartTime:1.0 * relativeDuration relativeDuration:relativeDuration animations:^{
self.topConstraint2.constant = 0;
[self.view layoutIfNeeded];
}];
[UIView addKeyframeWithRelativeStartTime:2.0 * relativeDuration relativeDuration:relativeDuration animations:^{
self.topConstraint3.constant = 0;
[self.view layoutIfNeeded];
}];
[UIView addKeyframeWithRelativeStartTime:3.0 * relativeDuration relativeDuration:relativeDuration animations:^{
self.topConstraint4.constant = 0;
[self.view layoutIfNeeded];
}];
[UIView addKeyframeWithRelativeStartTime:4.0 * relativeDuration relativeDuration:relativeDuration animations:^{
self.topConstraint5.constant = 0;
[self.view layoutIfNeeded];
}];
[UIView addKeyframeWithRelativeStartTime:5.0 * relativeDuration relativeDuration:relativeDuration animations:^{
self.topConstraint6.constant = 0;
[self.view layoutIfNeeded];
}];
} completion:nil];
Or, even simpler:
NSArray <NSLayoutConstraint *> *constraints = #[self.topConstraint1, self.topConstraint2, self.topConstraint3, self.topConstraint4, self.topConstraint5, self.topConstraint6];
CGFloat relativeDuration = 1.0 / (CGFloat) constraints.count;
[UIView animateKeyframesWithDuration:totalDuration delay:0 options:kNilOptions animations:^{
for (NSInteger i = 0; i < constraints.count; i++) {
[UIView addKeyframeWithRelativeStartTime: ((CGFloat) i) * relativeDuration relativeDuration:relativeDuration animations:^{
constraints[i].constant = 0;
[self.view layoutIfNeeded];
}];
}
} completion:nil];
That yields:
It would help if you showed all your code (how you setup the constraints, etc).
But, here is a quick example.
It creates 6 labels, with top constraints at 100. Tap the "Do Anim" button to animated them to Top: 0.0 ... tap again to animate back to 100:
#import "SequentialAnimViewController.h"
#interface SequentialAnimViewController () {
NSMutableArray *views;
NSMutableArray *topConstraints;
}
#end
#implementation SequentialAnimViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button addTarget:self action:#selector(animViews) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"Do Anim" forState:UIControlStateNormal];
button.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0];
button.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:button];
[button.centerXAnchor constraintEqualToAnchor:[self.view centerXAnchor]].active = YES;
[button.centerYAnchor constraintEqualToAnchor:[self.view centerYAnchor]].active = YES;
[button.widthAnchor constraintEqualToConstant:200.0].active = YES;
views = [NSMutableArray new];
topConstraints = [NSMutableArray new];
CGFloat x = 40.0;
CGFloat w = 40.0;
UILayoutGuide *g = [self.view safeAreaLayoutGuide];
for (int i = 0; i < 6; i++) {
UILabel *v = [UILabel new];
v.backgroundColor = [UIColor blueColor];
v.textColor = [UIColor yellowColor];
v.textAlignment = NSTextAlignmentCenter;
v.text = [NSString stringWithFormat:#"%i", i];
v.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:v];
[v.widthAnchor constraintEqualToConstant:w].active = YES;
[v.heightAnchor constraintEqualToConstant:w].active = YES;
[v.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:x].active = YES;
[topConstraints addObject:[v.topAnchor constraintEqualToAnchor:g.topAnchor constant:100.0]];
[views addObject:v];
x += w + 8;
}
[NSLayoutConstraint activateConstraints:topConstraints];
}
-(void)animViews {
__block int i = 0;
__block CGFloat newConstant = ((NSLayoutConstraint *)self->topConstraints[0]).constant == 0.0 ? 100.0 : 0.0;
((NSLayoutConstraint *)self->topConstraints[i++]).constant = newConstant;
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
((NSLayoutConstraint *)self->topConstraints[i++]).constant = newConstant;
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
((NSLayoutConstraint *)self->topConstraints[i++]).constant = newConstant;
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
((NSLayoutConstraint *)self->topConstraints[i++]).constant = newConstant;
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
((NSLayoutConstraint *)self->topConstraints[i++]).constant = newConstant;
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
((NSLayoutConstraint *)self->topConstraints[i++]).constant = newConstant;
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
NSLog(#"All Done!");
}];
}];
}];
}];
}];
}];
}
#end

UIPickerView Animate on and off screen behavior

This is a continuation of this question
CGRectMake : How To Calculate X and Y For UIPickerView Animation?
answered by https://stackoverflow.com/users/2315974/danypata
I have a picker view that I want to animate on and off screen on a button press and using the code in the previous question/answer I have got it to animate on screen the first time the button is pressed.
the second tome the button is pressed it just disappears and then the third time it is pressed it animates to the wrong place...please help
the code
if (self.pickerSort.hidden == NO) {
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.pickerSort.frame = CGRectMake(0,self.view.frame.size.height
+ self.pickerSort.frame.size.height,-self.pickerSort.frame.size.width,-self.pickerSort.frame.size.height);
}
completion:^(BOOL finished) {
}];
self.pickerSort.hidden = YES;
// [self performSelector:#selector(hidePicker) withObject:nil afterDelay:1];
} else if (self.pickerSort.hidden == YES) {
self.pickerSort.hidden = NO;
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.pickerSort.frame = CGRectMake(0 ,
self.view.frame.size.height
- self.pickerSort.frame.size.height,
self.pickerSort.frame.size.width,
self.pickerSort.frame.size.height);
}
completion:^(BOOL finished) {
}];
[self.view bringSubviewToFront:self.pickerSort];
Behavior in images - button press animates onto screen beautifully
Second Press it disappears with no animation
Third Press it animates to here
Any help would be great...functionality I am looking for is how to put the picker view back on an animation so the 3rd press is the same as the first
Please try to use the below code.
self.pickerSort.hidden = NO;
NSTimeInterval duration = 0.5;
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionCurveLinear
animations:^{
CGRect pickerFrame = self.pickerSort.frame;
// currently picker is off the screen, show it.
if (pickerFrame.origin.y == self.view.frame.size.height) {
// set frame to show picker
pickerFrame.origin.y = self.view.frame.size.height - self.pickerSort.frame.size.height;
} else {
// set frame to hide picker
pickerFrame.origin.y = self.view.frame.size.height;
}
self.pickerSort.frame = pickerFrame;
}
completion:^(BOOL finished) {
self.pickerSort.hidden = YES;
}];
After playing around with this and learning the ins and outs of frames and CGRects, I achieved this by using the following code
if (pickerSort.hidden == YES) {
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
pickerSort.hidden = NO;
visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[self.tableStations addSubview:visualEffectView];
pickerSort.frame = CGRectMake(0,0,originalPickerFrame.size.width,originalPickerFrame.size.height);
visualEffectView.frame = CGRectMake(0,0,originalPickerFrame.size.width,originalPickerFrame.size.height - 64);
}
completion:^(BOOL finished) {
self.navigationController.navigationItem.leftBarButtonItem.enabled = NO;
}];
}
else
{
visualEffectView.hidden = YES;
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
pickerSort.frame = CGRectMake(0,-originalPickerFrame.size.height,0,0);
}
completion:^(BOOL finished) {
self.navigationController.navigationItem.leftBarButtonItem.enabled = YES;
pickerSort.hidden = YES;
}];
}
I set the original frame size in viewDidLoad like so
pickerSort = [[UIPickerView alloc]initWithFrame:CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height)];
originalPickerFrame = pickerSort.frame;
pickerSort.frame = CGRectMake(0,-originalPickerFrame.size.height,0, 0);
Hope this can help somebody in the future

How to change the frame of a view with animations?

I am a beginner. I am updating the frame of a view. I am a bit confused about animations. I just want to know how to update the frame of a view with any kind of animations.
This is where I am updating my frames:
- (IBAction)btnCountries:(id)sender {
_dropDownView.hidden = NO;
fromCountry=YES;
fromCity = NO;
fromState = NO;
_dropDownView.frame = CGRectMake(132.0f, 63.0f, 172.0f, 308.0f);
[self.tblDropDown reloadData];
}
Any help is highly appreciated.
You can use UIView method animationWithDuration:
or CoreAnimation framework.
[UIView animateWithDuration:0.5 animations:^{
// animation here
_dropDownView.frame = CGRectMake(132.0f, 63.0f, 172.0f, 308.0f);
}];
[self.view setUserInteractionEnabled:NO];
[UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionTransitionNone
animations:^{
_dropDownView.frame = CGRectMake(132.0f, 63.0f, 172.0f, 308.0f);
}
completion:^(BOOL finished) {
[self.view setUserInteractionEnabled:YES];
}];
UIView support animation like as follows,
_dropDownView.hidden = NO;fromCountry=YES;
fromCity = NO;
fromState = NO;
UIView animateWithDuration:1.0f animations:^
{
_dropDownView.frame = CGRectMake(132.0f, 63.0f, 172.0f, 308.0f);
} completion:^(BOOL finished)
{
[self.tblDropDown reloadData];
}
Try below code
- (IBAction)btnCountries:(id)sender {
_dropDownView.hidden = NO;
fromCountry=YES;
fromCity = NO;
fromState = NO;
[UIView animateWithDuration:2.0
animations:^{
CGRect frame = _dropDownView.frame;
frame=CGRectMake(132.0f, 63.0f, 172.0f, 308.0f);
_dropDownView.frame = frame;
}
completion:^(BOOL finished){
[self.tblDropDown reloadData];
}];
}
Hope it helps you..

View animation issue

I'm trying to flip animate a view into another view, which corresponds of a small section of the screen. Both views have the same dimensions and center.
I keep getting as a result the animation of the full screen. From the code below, can somebody please let me know what the heck i'm doing wrong?
Thank you,
-j
+ (void) flipView:(UIView*)viewA toView:(UIView*)viewB wait:(Boolean)wait
{
// get parent view
UIView *parent = [viewA superview];
CGRect r = viewA.frame;
// create container view with the same dimensions as ViewA
UIView *containerView = [[UIView alloc] initWithFrame:viewA.bounds];
containerView.center = viewA.center;
// attache both views to intermidiate view
[containerView addSubview:viewA];
[containerView addSubview:viewB];
[viewA removeFromSuperview];
[parent addSubview:containerView];
viewB.alpha = 0;
viewA.alpha = 1;
// Perform the annimation
__block BOOL done = NO;
[UIView transitionWithView:viewA
duration:2.0
options: (UIViewAnimationOptionTransitionFlipFromTop)
animations:^{
viewA.alpha = 0;
viewB.alpha = 1; }
completion:^(BOOL finished) {
done = YES;
// detach all views
[viewA removeFromSuperview];
[viewB removeFromSuperview];
[containerView removeFromSuperview];
}
];
if(wait) {
while (done == NO)
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
}
First get rid of the old animation code (or at least commit it), it should look like this:
+ (void) flipView:(UIView*)viewA toView:(UIView*)viewB wait:(BOOL)wait
{
viewB.alpha = 0;
viewA.alpha = 1;
__block BOOL done = NO;
[UIView transitionWithView:viewA
duration:2.0
options: (UIViewAnimationOptionTransitionFlipFromTop)
animations:^{
viewA.alpha = 0;
viewB.alpha = 1; }
completion:^(BOOL finished) {
done = YES;
}
];
if(wait) {
while (!done)
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
}
Second, the superview of the subview that you want to transition is actually going to get the transition. So this means that you'll have to add viewA and viewB to a subview, add this subview to another view and then do the animation.
Here is a solution without any hacks with runloop. Just use the first message to run a transition to another view, and the second message to return to original state:
- (void) forwardTransitionFromView: (UIView *) viewA toView: (UIView *) viewB
{
NSAssert(viewA.superview, #"The 'from' view should be added to a view hierarchy before transition");
NSAssert(!viewB.superview, #"The 'to' view should NOT be added to a view hierarchy before transition");
CGSize viewASize = viewA.bounds.size;
viewB.frame = CGRectMake(0.0, 0.0, viewASize.width, viewASize.height);
[UIView transitionWithView:viewA
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[viewA addSubview:viewB];
}
completion:NULL];
}
- (void) backwardTransitionFromView: (UIView *) viewB toView: (UIView *) viewA
{
NSAssert([viewB.superview isEqual:viewA], #"The 'from' view should be a subview of 'to' view");
[UIView transitionWithView:viewA
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[viewB removeFromSuperview];
}
completion:NULL];
}
Why dont you flip both views in same direction?
-(void) FlipView:(bool) fromRight {
if(fromRight) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:view1 cache:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:view2 cache:YES];
[UIView commitAnimations];
}
else {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view1 cache:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view2 cache:YES];
[UIView commitAnimations];
}
}
and call the method like below:
[view1 setHidden:NO];
[self FlipView:YES];
[view2 setHidden:YES];
to reverse the animation:
[view2 setHidden:NO];
[self FlipView:NO];
[view1 setHidden:YES];

How to correctly enlarge an image from within a table view

I'm using the following code to zoom/enlarge an image from within a table view. I would like it to enlarge out to full screen. the current problem is that when it enlarges it enlarges only within the table cell (and as a result is partially hidden beneath the next table cell) instead of the full view.
-(void)zoomPhotoMethod :(id) sender
{
UITapGestureRecognizer *gesture = (UITapGestureRecognizer *) sender;
NSLog(#"Tag = %d", gesture.view.tag);
userSubmittedImageView = (UIImageView *)gesture.view;
if (!isFullScreen) {
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
//save previous frame
prevFrame = userSubmittedImageView.frame;
UIView *popupImageViewForTableCell = [[UIView alloc] initWithFrame: CGRectMake ( 0, 0, 320, 500)];
[userSubmittedImageView setFrame:[popupImageViewForTableCell bounds]];
}completion:^(BOOL finished){
isFullScreen = TRUE;
}];
return;
}
else{
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
[userSubmittedImageView setFrame:prevFrame];
}completion:^(BOOL finished){
isFullScreen = FALSE;;
}];
return;
}
}
updated code:
-(void)zoomPhotoMethod :(id) sender
{
UITapGestureRecognizer *gesture = (UITapGestureRecognizer *) sender;
NSLog(#"Tag = %d", gesture.view.tag);
userSubmittedImageView = (UIImageView *)gesture.view;
if (!isFullScreen) {
[UIView animateWithDuration:0.3 delay:0 options:0 animations:^{
//save previous frame
prevFrame = userSubmittedImageView.frame;
newView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)];
[self.view addSubview:newView];
UIView *popupImageViewForTableCell = [[UIView alloc] initWithFrame: CGRectMake ( 0, 0, 320, 500)];
[userSubmittedImageView setFrame:[popupImageViewForTableCell bounds]];
[newView addSubview:userSubmittedImageView];
[userSubmittedImageView setFrame:[newView bounds]];
}completion:^(BOOL finished){
isFullScreen = TRUE;
}];
return;
}
else{
[UIView animateWithDuration:0.3 delay:0 options:0 animations:^{
[userSubmittedImageView setFrame:prevFrame];
[newView setFrame:prevFrame];
}completion:^(BOOL finished){
isFullScreen = FALSE;;
}];
return;
}
}
What's happening is that you are still a subview of the tableview cell, so it's not going to be able to go outside of those bounds without being clipped.
To do what you want to do, you're going to have to:
Create a new UIImageView outside of your table view (add it as a subview outside of the tableview).
Set the image in the image view to the same image that you have in the tableview cell.
Start it at the same size and position as your tableview cell image.
Animate it up to where you want it.
When it's time to remove it, move it back down to the original tableview cell image.
Discard the imageview.
One way would be to use a copy of the image and place it outside the cell just above your original and animate this second image to full screen.
Another way would be to increase the tableView rowHeight and reload the section.

Resources