¿Animación letra por letra para UILabel?

¿Hay alguna forma de animar el text que muestra UILabel ? Quiero que muestre el carácter del valor del text por carácter.

Ayúdame con esta gente

Actualización para 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) } } } } } 

llamarlo es simple e hilo seguro:

 myLabel.animate(newText: myLabel.text ?? "May the source be with you", characterDelay: 0.3) 

@objC, 2012:

Prueba esta function de prototipo:

 - (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]; } } 

y llámalo de esta manera:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ [self animateLabelShowText:@"Hello Vignesh Kumar!" characterDelay:0.5]; }); 

Aquí está la respuesta de @Andrei G. como una extensión de 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) } } } } 

Esto podría ser mejor.

 - (void)viewDidLoad { [super viewDidLoad]; NSString *string =@"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]]; } 

He escrito una demostración, puedes usarla, es compatible con ios 3.2 y superior

en su file .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 networkingColor]]; 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]; } 

en su file .h

 @interface labeltextTestViewController : UIViewController { UILabel *label; NSTimer *timer; NSInteger i; NSString *text; } 

con la demo, creo que puedes hacer en tu situación, con un poco de cambio el código parece muy feo porque tengo que ir a cenar, puedes especializarte.

Swift 3, Aún crédito en concepto de Andrei G.

 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) } } } } 

He escrito una subclass de UILabel llamada CLTypingLabel , disponible en GitHub. Esto debería hacer lo que quieras.

Después de instalar CocoaPods, agregue el siguiente similar a su Podfile para usarlo:

 pod 'CLTypingLabel' 

Código de muestra

Cambie la class de una label de UILabel a CLTypingLabel; introduzca la descripción de la imagen aquí

 @IBOutlet weak var myTypeWriterLabel: CLTypingLabel! 

En time de ejecución, establecer el text de la label activará la animation automáticamente:

 myTypeWriterLabel.text = "This is a demo of typing label animation..." 

Puede personalizar el intervalo de time entre cada carácter:

 myTypeWriterLabel.charInterval = 0.08 //optional, default is 0.1 

Puede pausar la animation de escritura en cualquier momento:

 myTypeWriterLabel.pauseTyping() //this will pause the typing animation myTypeWriterLabel.continueTyping() //this will continue paused typing animation 

También hay un proyecto de ejemplo que viene con cocoapods

No hay un comportamiento pnetworkingeterminado en UILabel para hacer esto, puede crear el suyo donde agrega cada letra una a la vez, en function de un timer

OK base en la primera respuesta esto es lo que escribí

  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 } } } 

Basado en la respuesta @Adam Waite. Si alguien quisiera usar esto con un cierre de finalización.

  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() } } } 

Modificación del código @Adam Waite (buen trabajo, por cierto) para mostrar el text palabra por palabra:

  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) } } 

Una pequeña mejora en la respuesta brindada por Andrei, para no bloquear el hilo principal.

 - (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; }