Анимация UILabel за пределами UILabel

#ios #uilabel #core-animation #calayer

#iOS #uilabel #ядро-анимация #calayer

Вопрос:

У меня есть метка, и я хочу эффект «спидометра»; когда тексту метки присваивается новое значение, я бы хотел, чтобы старое значение прокручивалось вверх, а новое вводилось снизу. Я не знаю, как этого добиться. Это то, что я использую в настоящее время;

   CATransition *animation = [CATransition animation];
  animation.duration = .2f;
  animation.type = kCATransitionPush;
  animation.subtype = kCATransitionFromBottom;
  animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
  animation.removedOnCompletion = YES;

  [mylabel.layer addAnimation:animation
                       forKey:@"changeTextTransition"];

  mylabel.text = @"new text";
  

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

Я попытался создать маску для слоя и привязать маску слоя к границам, но это не дало никакого эффекта:

   UIImageView *maskView = [[UIImageView alloc] initWithImage:labelMask];
  // this image is a png that is the same dimensions as the label, and is 100% opaque and colored white
  maskView.frame = mylabel.frame;
  mylabel.layer.mask = maskView.layer;
  mylabel.layer.masksToBounds = YES;
  

Я даже попробовал альтернативный метод создания маски:

   CALayer *maskLayer = [CALayer new];
  maskLayer.frame = mylabel.frame;
  maskLayer.contents = (id)(labelMask.CGImage); // same image as above
  maskLayer.contentsRect = mylabel.bounds;
  mylabel.layer.mask = maskLayer;
  mylabel.layer.masksToBounds = YES;
  

Это не имело никакого эффекта.

Что еще я могу попробовать, чтобы предотвратить утечку анимации слоя за пределы UILabel?

Комментарии:

1. Это может быть очевидно, но как насчет `myLabel.ClipToBounds = YES;’?

2. @rmaddy Это не сработает, потому что я анимирую CALayer UILabel; UILabel не может осуществлять какой-либо контроль над своим собственным слоем. приведенный ниже ответ daniel.gindi решает проблему, помещая UILabel в другой контейнер (UIView) и заставляя этот контейнер управлять поведением его вложенных представлений, в данном случае view clipsToBounds .

Ответ №1:

Вы перемещаете сам UILabel слой с анимацией, а UILabel s clipsToBounds (UIView) / masksToBounds (CALayer) ограничивает сам UILabel слой в целом.

Чтобы было понятнее: если вы поместите что-то внутрь метки UILabel или попытаетесь отобразить что-то большее на слое метки, оно будет обрезано маской. Но если бы вы просто переместили метку куда-нибудь еще в родительском представлении — тогда она осталась бы целой, поскольку маска перемещается вместе с ней…

Даже при анимации это точно такая же ситуация. Маска перемещается вместе со слоем.

Таким образом, решение содержит UILabel внутри другого UIView , который сам имеет clipsToBounds набор. Это также позволило бы вам создать подкласс UIView , который является мини-контроллером, управляет своими собственными метками, анимирует их и т.д. По требованию с простым интерфейсом в UIView подклассе. (Я предполагаю, что это то, что вы делаете, и вы просто забыли установить clipsToBounds в представлении контейнера …)

Комментарии:

1. Ya veo! Спасибо за объяснение, оно очень поучительное.

2. не отображается полный текст метки, если я уменьшаю границы, а затем анимирую размер текста при использовании автозаполнения. Даже если поместить метку в поле зрения