UIVIew анимация - масштабирование + перевод - PullRequest
10 голосов
/ 18 августа 2010

У меня есть вид, который я хочу масштабировать и перевести на новое место, анимировав его. Я пытался добиться этого с помощью следующего кода:

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:kDurationForFullScreenAnimation];
[[self animatingView] setFrame:finalRect];
[UIView commitAnimations];

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

Эта проблема уже обсуждалась в нескольких других темах, но ни один из них не пришел к выводу. Однако существует решение использовать таймер и каждый раз устанавливать кадр в обратном вызове таймера, но у него есть недостаток производительности.

Каково наиболее подходящее решение этой проблемы, также, почему в первом случае эта проблема возникает?

Спасибо

Ответы [ 3 ]

33 голосов
/ 18 августа 2010

Установка рамки не делает ни масштаб, ни перевод.Вы используете неверную терминологию или используете не тот инструмент для этой работы.Масштабирование и преобразование выполняются с использованием аффинных преобразований Core Graphics, когда вы хотите повлиять на UIView (в отличие от слоя, использующего преобразования Core Animation).

Для масштабирования представления используйте

// 2x
[rotationView setTransform:CGAffineTransformMakeScale(2.0, 2.0)];

Для перевода используйте

// Move origin by 100 on both axis
[rotationView setTransform:CGAffineTransformMakeTranslation(100.0, 100.0)];

Чтобы анимировать их, оберните их в блок анимации.Если вы хотите преобразовать вид с помощью обоих этих методов, вам нужно объединить их.

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

[view setBounds:newRect];
[view setCenter:newCenter];

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

15 голосов
/ 01 сентября 2012

Вот пример с блочной анимацией:

CGPoint newCenter = CGPointMake(100.0,100.0);

[UIView animateWithDuration: 1
                      delay: 0
                    options: (UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction)
                 animations:^{object.center = newCenter ; object.transform = CGAffineTransformScale(CGAffineTransformIdentity, 2.0, 2.0);}
                 completion:^(BOOL finished) { }
];
5 голосов
/ 11 марта 2014

Попробуйте это решение:

  CGAffineTransform s =  CGAffineTransformMakeScale(0.5f,0.5f);
  CGAffineTransform t = CGAffineTransformMakeTranslation(100, 0);
  v2.transform = CGAffineTransformConcat(t,s); // not s,t

эта операция не является коммутативной. Порядок противоположен порядку при использовании вспомогательных функций для применения одного преобразования к другому.

И вы можете использовать эту операцию для: например (удаления шкалы):

    v2.transform =
    CGAffineTransformConcat(CGAffineTransformInvert(s), v2.transform);
...