1

I am using autolayout with this layout:

enter image description here

self.view with frame (0,80, 320, 488)

collectionView with frame (0,0,320,220)

underView with frame (0,220,320,268)

and trying to achieve an animation which should resize underView enlarging its height such that underView partially covers collectionView moving bottom-up.

Autolayout forces an height constraint for those 2 views hence I have created an IBOutlet for underView height constraint which I am tweaking in animation:

NSLog(@"underView height %.2f", self.underView.frame.size.height);

NSLog(@"offset (%.2f, %.2f)", offset.x, offset.y);

heightConstraint.constant += offset.y;

NSLog(@"heightConstraint %.2f", heightConstraint.constant);

[self.underView setNeedsUpdateConstraints];

[UIView animateWithDuration:ANIMATION_DURATION
                      delay:ANIMATION_DELAY
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^{

                     [self.underView layoutIfNeeded];

                     NSLog(@"underView height %.2f", heightConstraint.constant);

                 } completion:nil];

And in the console I can see:

2013-07-30 09:09:37.268 Cal[49611:a0b] underView height 268.00
2013-07-30 09:09:37.268 Cal[49611:a0b] offset (320.00, 144.00)
2013-07-30 09:09:37.269 Cal[49611:a0b] heightConstraint 412.00
2013-07-30 09:09:37.270 Cal[49611:a0b] underView height 412.00

But the resize does not happen at all.

The only reason for this behavior I can think of is the height constraint of the collectionView above, but since I do not want the collection to reload I can not operate on that.

I am wondering how to achieve having the underView enlarging OVER the collectionView? I tried using constraint priorities but it didn't work...

Fabrizio Prosperi
  • 1,398
  • 4
  • 18
  • 32

2 Answers2

2

Try the following, as per this answer. Make sure you call layoutIfNeeded on the superview:

[UIView animateWithDuration:ANIMATION_DURATION
                      delay:ANIMATION_DELAY
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^{

                     heightConstraint.constant += offset.y;
                     [self.view layoutIfNeeded];

                     } 
                 completion:nil];
Community
  • 1
  • 1
Maarten
  • 1,873
  • 1
  • 13
  • 16
  • Thank you @Maarten, but actually this doesn't make any difference, and besides, if you read the comments to the answer you linked people have confirmed that the constant update can well stay out from the animation, leaving only the layoutIfNeeded method in the animation block. As an additional hint I have tried also to call [self.view layoutIfNeeded] as someone pointed out is the superview which needs to redisplay layout, but nothing changed again. – Fabrizio Prosperi Jul 30 '13 at 09:59
  • Have you tried calling `layoutIfNeeded` on the superView? I changed my answer to reflect this. – Maarten Jul 30 '13 at 11:54
  • Yes, as I said above, self.view is the superview. – Fabrizio Prosperi Jul 30 '13 at 12:38
  • But in your code you call `layoutIfNeeded` on `underView`, not `self.view`, like I did in my answer. – Maarten Jul 30 '13 at 12:57
  • @Marteen, in my first comment above :"As an additional hint I have tried also to call [self.view layoutIfNeeded] as someone pointed out is the superview which needs to redisplay layout, but nothing changed again". – Fabrizio Prosperi Jul 30 '13 at 13:07
0

So, I have found a possible solution to my question, not sure if it is the best solution though. I was missing a reference to the vertical space constraint of self.collectionView, so the final code would be:

verticalSpace.constant -= shift;
heightConstraint.constant += shift;

[self.collectionView setNeedsUpdateConstraints];
[self.underView setNeedsUpdateConstraints];

[UIView animateWithDuration:ANIMATION_DURATION
                      delay:ANIMATION_DELAY
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^{
                     [self.view layoutIfNeeded];
                 } completion:nil
 ];

I will wait other better solutions for some time so that I don't mark my own answer as the accepted one.

Fabrizio Prosperi
  • 1,398
  • 4
  • 18
  • 32