Правильный способ анимации положения и размера UIView с изображением (этот метод не работает в Xcode 6)?

У меня есть приложение, в котором я одновременно анимирую положение и размер UIView с изображением, вызывая setFrame внутри animateWithDuration, таким образом:

UIImage *image = [UIImage imageNamed: imageName];    
[_faceView setImage: image];
[_faceView setFrame: CGRectMake(-40.0, 0.0, 40.0, 40.0)];
  [UIView animateWithDuration:0.5 animations:^{
    [_faceView setFrame: CGRectMake(80.0, 140.0, 160, 160)];
}
completion:^(BOOL finished) {}

При компиляции в Xcode 5 и запуске в iOS 7 или iOS 8 я получил правильное поведение, используя вышеуказанную методологию.

Теперь, компилируя в Xcode 6 (и, следовательно, в сравнении с SDK 8.0, что, как я полагаю, является определяющей разницей?) и работая в iOS 7 или iOS 8, этот код не дает правильного результата: кажется, что происходит то, что изображение анимируется до своего «естественного» размера, а не до указанного в CGRect.

Итак: (а) кто-нибудь знает, почему это может быть? и (б) в любом случае, основная проблема в том, что я делаю что-то не так? -- есть ли более "правильный" способ добиться анимации положения/размера изображения в UIView, который позволит достичь желаемого результата?


person Neil Coffey    schedule 02.10.2014    source источник
comment
вы не можете просто анимировать ограничения? Или это явно не должно использовать автоматическую компоновку?   -  person Daniel Galasko    schedule 04.11.2014
comment
Дело не в том, что это не должно быть явно, просто это проект, который я настроил до Xcode 6, и я пытаюсь обновить некоторые его части с минимальными усилиями, не переписывая всю вселенную...!   -  person Neil Coffey    schedule 04.11.2014
comment
Вот пример, я создал его с помощью Xcode 6 и это работает нормально.   -  person gabbler    schedule 05.11.2014
comment
Я так понимаю, что нет никакого флага, который я могу установить для представления, чтобы сказать, пожалуйста, полностью исключите это представление из автоматического макета и просто поместите его туда, где я вам скажу, и не принимайте во внимание его при принятии решения о том, где разместить другие представления...?   -  person Neil Coffey    schedule 05.11.2014
comment
Я считаю, что вы можете использовать translatesAutoresizingMaskIntoConstraints для этого   -  person sha    schedule 05.11.2014


Ответы (2)


По умолчанию в Xcode6, даже если у вас нет никаких ограничений, связанных с представлением, IB создаст ограничения по умолчанию. Вот почему после установки вид кадра перемещается на исходный кадр.

Вы можете добавить строку

_faceView.translatesAutoresizingMaskIntoConstraints = YES;

И это, по сути, сломает существующие ограничения, но вы получите правильную анимацию.

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

person sha    schedule 02.10.2014
comment
Поэтому я использовал эту опцию, и тогда анимация была правильной, но как только анимированный вид перемещается, он сбивает позиции/размеры других элементов в представлении. Это БЕЗУМИЕ!!!! Итак... как бы я использовал ограничения автоматического макета, чтобы просто перемещать представление по экрану, не испортив другие вещи? - person Neil Coffey; 04.11.2014
comment
Если вы обновили свой вид с ограничениями автоматического макета, то анимация будет довольно простой. Просто выставьте необходимые ограничения в качестве выхода (например, расстояние от вершины и ширину вида) и измените эти ограничения внутри блока анимации. - person sha; 04.11.2014

Я думаю, вы можете попробовать начать использовать Autolayout для создания анимации. Насколько я помню, это было рекомендовано на сессии WWDC.

В качестве простейшего примера, если вы хотите переместить вид вправо на 40 точек в анимации, вы можете добавить ограничение влево, использовать Interface Builder, чтобы связать его с IBOutlet как

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *leftConstraint;

И код анимации выглядит следующим образом:

- (IBAction)animatinoButtonPressed:(id)sender {
    self.leftConstraint.constant = self. leftConstraint.constant + 40.f;
    [UIView animateWithDuration:3.f animations:^{
        [self.view layoutIfNeeded];
    }];
}

Метод layoutIfNeeded заставит представление немедленно переставить подпредставления, которые перемещают целевое представление и создают анимацию.

Я думаю, вы можете создать подходящие ограничения в вашем случае и сделать правильную анимацию.

person Xiangyu.Wu    schedule 10.11.2014