Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Graham Connolly
Graham Connolly
25,475 Points

Animating views does not seem to work in iOS8 but did in iOS7

HI guys,

Im wondering is this a bug in iOS8 and XCode 6. I can no longer animate a view to a new position on the screen. I log the views frame that I want to animate and the frame is updated, but its like it is not redrawn on the screen. The block of code below works in iOS7 but seems to just jerk up and back to its original position.

[UIView 
  transitionWithView:self.view 
  duration:0.3 
  options:UIViewAnimationOptionCurveEaseInOut 
  animations:^{
    self.image.frame = CGRectMake(0, self.view.bounds.size.height - 252, self.view.bounds.size.width, self.table.frame.size.height);
  } 
  completion:nil];

What type of object is self.image? Is it an UIImageView or UIImage?

Also, another tip, you can get the height and width of the view using some of the CGGeometry helpers.

CGFloat height = CGRectGetHeight(self.view.bounds);
CGFloat width = CGRectGetWidth(self.view.bounds);
CGFloat tableHeight = CGRectGetHeight(self.table.frame);
Graham Connolly
Graham Connolly
25,475 Points

self.image is a UIImageView. I managed to find a solution. If you programmatically create your UIElement, in this case a UIImageView, the animation will work. However if you place the UIElement on the storyboard using interface builder the animation does not work. I am guessing is to do with new uiview constraints added in iOS8.

Thanks for the tip, I never new this.

Did you hook up your IBOutlet to the UIImageView when you dropped it in the Storyboard?

Graham Connolly
Graham Connolly
25,475 Points

I did indeed. It worked perfectly in iOS7, but it doesn't now. It was an old project built in iOS7 that is now compiled for iOS8. It effected all animations in my app. The animation would start, but when it finishes, it would jolt back to its original position. Have you tried replicating the problem?

I just realized you're using the -transitionWithView:duration:options:animations:completion: method which is really meant to transition from one view to another, usually in conjunction with child view controllers.

Try this instead:

[UIView 
  animateWithDuration:0.3 
  delay:0.0 
  options:UIViewAnimationOptionCurveEaseInOut 
  animations:^{
    self.image.frame = CGRectMake(0, CGRectGetHeight(self.view.bounds) - 252, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.table.frame));
  } 
  completion:nil];
Graham Connolly
Graham Connolly
25,475 Points

Thanks Marshal, I tried this but this no luck. In one view I can get the tableview to animate off screen, but when I interact with the screen it jolts back up, rather strange and very annoying. :(

EDIT: I got it to work by removing use auto layout in interface builder. Autolayout in iOS8 must interfere with the position of views. Hence why programmatically creating views works. This is a bummer because I want to use autolayout.

EDIT2: Add Auto layout to the image, and adjusting the relevant constraint in the animation made it work.

  1. add constraints to element
  2. In IB click on the constraint you would like to adjust, and connect it as an IBOutlet.

Then in your code;

    self.imageViewTop.constant=-CGRectGetHeight(self.image.bounds);
    [self.image setNeedsUpdateConstraints];
    [UIView animateWithDuration:0.5  delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{

        [self.image layoutIfNeeded];


        } completion:nil];

This would move the image upwards to the amount of pixels specified by:

CGRectGetHeight(self.image.bounds);