Плавная анимация кадра UILabel

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

// Assume myLabel frame starts as (0, 0, 100, 200) 
[UIView beginAnimations:@"myAnim" context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDuration:1.0];
myLabel.frame = CGRectMake(0.0, 0.0, 50, 100);
[UIView commitAnimations];  

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

Предварительная анимация

Пост-анимация

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

Итак, вопрос в том, как мне этого избежать?

Спасибо за любую помощь,
Скотт


person Scott Little    schedule 13.11.2009    source источник
comment
Это старый вопрос, но я борюсь с той же проблемой. Как-то это нелогично. Насколько я понимаю методы анимации, вы должны иметь возможность анимировать большинство свойств класса UIView. Но почему свойство frame UILabel при анимации ведет себя иначе, чем обычный подкласс UIView. Похоже, что класс UILabel игнорирует анимацию для размера и только анимирует изменение местоположения. Это создает довольно странную анимацию. Я был бы признателен, если бы кто-нибудь мог мне помочь с этим.   -  person Chris    schedule 12.11.2010


Ответы (5)


Ура, что ответил на двухлетний мертвый вопрос, но я нашел ответ. Либо в Интерфейсном Разработчике, либо в коде измените свойство contentMode метки. Кажется, ваш установлен на scaleToFill; попробуйте left или right.

person cliclcly    schedule 06.07.2011
comment
Если бы я мог, я бы добавил в этот ответ 100! (Он все еще иногда прыгает, но это нормально) - person Ariel; 29.11.2011
comment
TopLeft / Right или BottomLeft / Right могут быть правильным contentMode, который вам нужен, в зависимости от конкретной анимации, которая вам нужна. - person CedricSoubrie; 30.03.2014
comment
это спасло мне жизнь :) - person Dmitry; 18.01.2017
comment
этот ответ на 100% работает, но для большей ясности, если мой .textAlignment был .center, как в: myLabel.textAlignment = .center, тогда установите .contentMode на: myLabel.contentMode = .center - person Lance Samaria; 18.05.2021

Чтобы расширить ответ @ cliclcly: из обзора документации UILabel:

Режим содержимого по умолчанию для класса UILabel - UIViewContentModeRedraw. Этот режим заставляет представление перерисовывать свое содержимое каждый раз, когда изменяется его ограничивающий прямоугольник. Вы можете изменить этот режим, изменив унаследованное свойство contentMode класса.

Из документации свойства contentMode UIView:

Значение этого свойства по умолчанию - UIViewContentModeScaleToFill.

UILabels по умолчанию ведут себя иначе, чем другие UIView, потому что их свойство contentMode по умолчанию отличается.

person titaniumdecoy    schedule 02.10.2012

Я обнаружил, что анимация кадров UIlabel странная - их размер сразу устанавливается равным конечному размеру, а текст отображается для этого размера. После этого анимируется только изменение позиции, что означает, что если размер назначения равен (0,0), то метка немедленно исчезает. Чтобы обойти это ограничение, я разместил метку внутри представления того же размера, что и вложенные представления, отключил автоматическое изменение размера для метки, и я анимирую супервизор метки вместо самой метки. Конечным результатом является то, что рамка метки полностью анимирована, но содержащийся текст не перерисовывается, скажем, с другим размером шрифта, и при этом не изменяется усечение текста. Он все еще не идеален, но подходит для моей цели.

Исходный кадр:

начальный кадр

Во время анимации:

Во время анимации

Анимация закончилась:

Анимация завершена

person user3099609    schedule 06.03.2014
comment
Не могу поверить, что я никогда не знал этого о UILabels. Но вы помогли мне решить проблему, которая поставила меня в тупик - спасибо! - person Echelon; 08.03.2016

Анимация кадра не приводит к изменению размера шрифта. Если я понимаю, что вы наблюдаете за поведением, я думаю, что у вас adjustsFontSizeToFitWidth метки установлено на «Истина», так что вы видите, что кадр анимируется до размера, за которым следует мгновенная корректировка размера шрифта.

Вы можете попытаться масштабировать преобразование метки так, чтобы рамка и шрифт масштабировались одновременно.

person TechZen    schedule 13.11.2009
comment
На самом деле нет, это не так. AdjustFontSizeToFitWidth здесь не установлен, и я на самом деле не пытаюсь изменить размер шрифта, только рамку, которая выделена желтым цветом. Однако происходит то, что целевой фрейм (в данном случае) соответствует тексту, поэтому он сначала перерисовывает этот слой, растягивает его до размеров исходного фрейма, а затем уменьшает его. Вот почему это выглядит так странно. - person Scott Little; 18.11.2009
comment
тогда не уверен. Это интересная проблема. Я посмотрю, смогу ли я воспроизвести это позже сегодня. Мне самому любопытно. - person TechZen; 18.11.2009

Просто отключите автоматический макет для вашей этикетки.

В Xcode щелкните метку, а затем на панели свойств снимите флажок с опции автоматического макета.

person farid98    schedule 23.12.2013