Есть ли способ анимировать текст, отображаемый UILabel
. Я хочу, чтобы он отображал текстовый символ значения по символу.
Помогите мне с этими людьми
Есть ли способ анимировать текст, отображаемый UILabel
. Я хочу, чтобы он отображал текстовый символ значения по символу.
Помогите мне с этими людьми
Обновление для 2017, Swift 3:
extension UILabel {
func animate(newText: String, characterDelay: TimeInterval) {
DispatchQueue.main.async {
self.text = ""
for (index, character) in newText.characters.enumerated() {
DispatchQueue.main.asyncAfter(deadline: .now() + characterDelay * Double(index)) {
self.text?.append(character)
}
}
}
}
}
вызов простой и потокобезопасный:
myLabel.animate(newText: myLabel.text ?? "May the source be with you", characterDelay: 0.3)
@objC, 2012:
Попробуйте эту функцию прототипа:
- (void)animateLabelShowText:(NSString*)newText characterDelay:(NSTimeInterval)delay
{
[self.myLabel setText:@""];
for (int i=0; i<newText.length; i++)
{
dispatch_async(dispatch_get_main_queue(),
^{
[self.myLabel setText:[NSString stringWithFormat:@"%@%C", self.myLabel.text, [newText characterAtIndex:i]]];
});
[NSThread sleepForTimeInterval:delay];
}
}
и назовите его следующим образом:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
^{
[self animateLabelShowText:@"Hello Vignesh Kumar!" characterDelay:0.5];
});
Здесь @Andrei G. отвечает как расширение Swift:
extension UILabel {
func setTextWithTypeAnimation(typedText: String, characterInterval: NSTimeInterval = 0.25) {
text = ""
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)) {
for character in typedText.characters {
dispatch_async(dispatch_get_main_queue()) {
self.text = self.text! + String(character)
}
NSThread.sleepForTimeInterval(characterInterval)
}
}
}
}
Это может быть лучше.
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *string [email protected]"Risa Kasumi & Yuma Asami";
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:string forKey:@"string"];
[dict setObject:@0 forKey:@"currentCount"];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(typingLabel:) userInfo:dict repeats:YES];
[timer fire];
}
-(void)typingLabel:(NSTimer*)theTimer
{
NSString *theString = [theTimer.userInfo objectForKey:@"string"];
int currentCount = [[theTimer.userInfo objectForKey:@"currentCount"] intValue];
currentCount ++;
NSLog(@"%@", [theString substringToIndex:currentCount]);
[theTimer.userInfo setObject:[NSNumber numberWithInt:currentCount] forKey:@"currentCount"];
if (currentCount > theString.length-1) {
[theTimer invalidate];
}
[self.label setText:[theString substringToIndex:currentCount]];
}
Я написал демо, вы можете использовать его, он поддерживает ios 3.2 и выше
в вашем .m файле
- (void)displayLabelText
{
i--;
if(i<0)
{
[timer invalidate];
}
else
{
[label setText:[NSString stringWithFormat:@"%@",[text substringToIndex:(text.length-i-1)]]];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 60)];
[label setBackgroundColor:[UIColor redColor]];
text = @"12345678";
[label setText:text];
[self.view addSubview:label];
i=label.text.length;
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(displayLabelText) userInfo:nil repeats:YES];
[timer fire];
}
в вашем .h файле
@interface labeltextTestViewController : UIViewController {
UILabel *label;
NSTimer *timer;
NSInteger i;
NSString *text;
}
с демо, я думаю, что вы можете сделать в своей ситуации, с небольшим изменением код выглядит очень очень уродливо, потому что мне нужно пойти на ужин, вы можете его мажорировать.
Swift 3, по-прежнему кредитует концепцию Андрея Г.
extension UILabel{
func setTextWithTypeAnimation(typedText: String, characterInterval: TimeInterval = 0.25) {
text = ""
DispatchQueue.global(qos: .userInteractive).async {
for character in typedText.characters {
DispatchQueue.main.async {
self.text = self.text! + String(character)
}
Thread.sleep(forTimeInterval: characterInterval)
}
}
}
}
Я написал небольшую библиотеку специально для этого случая использования CLTypingLabel, доступный в GitHub.
Он эффективен, безопасен и не спит нить. Он также обеспечивает интерфейс pause
и continue
. Назовите его в любое время, и он не сломается.
После установки CocoaPods добавьте следующее, например, в ваш подфайл:
pod 'CLTypingLabel'
Измените класс метки с UILabel на CLTypingLabel;
@IBOutlet weak var myTypeWriterLabel: CLTypingLabel!
Во время выполнения заданный текст метки автоматически запускает анимацию:
myTypeWriterLabel.text = "This is a demo of typing label animation..."
Вы можете настроить временной интервал между каждым символом:
myTypeWriterLabel.charInterval = 0.08 //optional, default is 0.1
Вы можете приостановить анимацию ввода в любое время:
myTypeWriterLabel.pauseTyping() //this will pause the typing animation
myTypeWriterLabel.continueTyping() //this will continue paused typing animation
Также есть образец проекта, который поставляется с cocoapods
В UILabel нет поведения по умолчанию, чтобы сделать это, вы можете сделать свой собственный, где вы добавляете каждую букву по одному, на основе таймера
OK, основываясь на первом ответе, это то, что я написал
import Foundation
var stopAnimation = false
extension UILabel {
func letterAnimation(newText:NSString?,completion:(finished:Bool) -> Void){
self.text = ""
if !stopAnimation {
dispatch_async(dispatch_queue_create("backroundQ", nil)){
if var text = newText {
text = (text as String) + " "
for(var i = 0; i < text.length;i++){
if stopAnimation {
break
}
dispatch_async(dispatch_get_main_queue()) {
let range = NSMakeRange(0,i)
self.text = text.substringWithRange(range)
}
NSThread.sleepForTimeInterval(0.05)
}
completion(finished:true)
}
}
self.text = newText as? String
}
}
}
Я знаю, что слишком поздно для ответа, но на всякий случай для тех, кто ищет анимацию ввода в UITextView. Я написал небольшую библиотеку Github для Swift 4. Вы можете установить обратный вызов после завершения анимации.
@IBOutlet weak var textview:TypingLetterUITextView!
textview.typeText(message, typingSpeedPerChar: 0.1, completeCallback:{
// complete action after finished typing }
Кроме того, у меня есть расширение UILabel для ввода анимации.
label.typeText(message, typingSpeedPerChar: 0.1, didResetContent = true, completeCallback:{
// complete action after finished typing }
На основе ответа @Adam Waite. Если кто-то хотел бы использовать это с закрытием закрытия.
func setTextWithTypeAnimation(typedText: String, characterInterval: NSTimeInterval = 0.05, completion: () ->()) {
text = ""
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)) {
for character in typedText.characters {
dispatch_async(dispatch_get_main_queue()) {
self.text = self.text! + String(character)
}
NSThread.sleepForTimeInterval(characterInterval)
}
dispatch_async(dispatch_get_main_queue()) {
completion()
}
}
}
Изменение кода @Adam Waite (хорошая работа, кстати) для отображения текстового слова по слову:
func setTextWithWordTypeAnimation(typedText: String, characterInterval: NSTimeInterval = 0.25) {
text = ""
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)) {
let wordArray = typedText.componentsSeparatedByString(" ")
for word in wordArray {
dispatch_async(dispatch_get_main_queue()) {
self.text = self.text! + word + " "
}
NSThread.sleepForTimeInterval(characterInterval)
}
}
Небольшое улучшение ответа, предоставленного Андреем, чтобы не блокировать основной поток.
- (void)animateLabelShowText:(NSString*)newText characterDelay:(NSTimeInterval)delay
{
[super setText:@""];
NSTimeInterval appliedDelay = delay;
for (int i=0; i<newText.length; i++)
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, appliedDelay * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[super setText:[NSString stringWithFormat:@"%@%c", self.text, [newText characterAtIndex:i]]];
});
appliedDelay += delay;
}