Изменение размера UIView с помощью автомакета при размещении ниже UIView фиксированного размера

Я использую autolayout с этим макетом:

введите здесь описание изображения

селфи с рамкой (0,80, 320, 488)

collectionView с рамкой (0,0,320,220)

нижний вид с рамкой (0,220,320,268)

и попытка добиться анимации, которая должна изменять размер underView, увеличивая его высоту, так что underView частично покрывает collectionView, перемещаясь снизу вверх.

Autolayout устанавливает ограничение по высоте для этих двух представлений, поэтому я создал IBOutlet для ограничения высоты underView, которое я настраиваю в анимации:

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

И в консоли я вижу:

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

Но ресайза вообще не происходит.

Единственная причина такого поведения, о которой я могу думать, - это ограничение высоты collectionView выше, но, поскольку я не хочу, чтобы коллекция перезагружалась, я не могу работать с этим.

Мне интересно, как добиться увеличения нижнего представления над коллекцией? Я пытался использовать приоритеты ограничений, но это не сработало...


person Fabrizio Prosperi    schedule 30.07.2013    source источник


Ответы (2)


Попробуйте следующее, как указано в этом ответе. Убедитесь, что вы вызываете layoutIfNeeded в супервизоре:

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

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

                     } 
                 completion:nil];
person Maarten    schedule 30.07.2013
comment
Спасибо @Maarten, но на самом деле это не имеет никакого значения, и, кроме того, если вы читаете комментарии к ответу, на который вы ссылаетесь, люди подтверждают, что постоянное обновление вполне может оставаться вне анимации, оставляя только метод layoutIfNeeded в блок анимации. В качестве дополнительной подсказки я также попытался вызвать [self.view layoutIfNeeded], поскольку кто-то указал, что это суперпредставление, которому необходимо повторно отобразить макет, но снова ничего не изменилось. - person Fabrizio Prosperi; 30.07.2013
comment
Вы пытались вызвать layoutIfNeeded в superView? Я изменил свой ответ, чтобы отразить это. - person Maarten; 30.07.2013
comment
Да, как я уже сказал выше, self.view — это супервизия. - person Fabrizio Prosperi; 30.07.2013
comment
Но в вашем коде вы вызываете layoutIfNeeded для underView, а не self.view, как я сделал в своем ответе. - person Maarten; 30.07.2013
comment
@Marteen, в моем первом комментарии выше: в качестве дополнительной подсказки я также пытался вызвать [self.view layoutIfNeeded], поскольку кто-то указал, что это суперпредставление, которому необходимо повторно отобразить макет, но снова ничего не изменилось. - person Fabrizio Prosperi; 30.07.2013

Итак, я нашел возможное решение своего вопроса, но не уверен, что это лучшее решение. Мне не хватало ссылки на ограничение по вертикали для self.collectionView, поэтому окончательный код будет таким:

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

Я подожду какое-то время других лучших решений, чтобы не отмечать свой ответ как принятый.

person Fabrizio Prosperi    schedule 30.07.2013