#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. не отображается полный текст метки, если я уменьшаю границы, а затем анимирую размер текста при использовании автозаполнения. Даже если поместить метку в поле зрения