2010-09-17 12 views
30

Me gustaría mostrar un mensaje temporal en el iPhone/iPad que muestra la confirmación de una acción, o algún estado rápido sobre alguna actividad de fondo.Cómo mostrar un mensaje emergente temporal en iPhone/iPad/iOS

¿Hay un control estándar para hacer esto? He visto aplicaciones hacer esto. Un rectángulo redondeado, oscuro y parcialmente transparente con texto dentro. No solicita la entrada del usuario, pero desaparece por sí solo en un corto período de tiempo. Android tiene una construcción similar que es estándar. También similar a las ventanas que muestra Growl.

Sugerencias apreciadas.

Respuesta

15

Hay una biblioteca de usuario en cocoacontrols.com que emula las ventanas emergentes de Toast estilo Android. Puede ser lo que estás buscando.

http://www.cocoacontrols.com/platforms/ios/controls/altoastview

Hay también éste que sigue la misma idea.

http://www.cocoacontrols.com/platforms/ios/controls/itoast

+1

Esto es lo más cercano a lo que estaba buscando, aunque terminé escribiendo el mío. – David

+0

Encontré ALToastView útil, gracias! –

+1

Actualización: El siempre popular [MBProgressHUD] (https://github.com/jdg/MBProgressHUD) ahora tiene una [notificación similar a un brindis] (http://dl.dropbox.com/u/378729/MBProgressHUD/7. png). –

9

Utilice UIAlertView. Aquí hay un enlace rápido a un ejemplo sencillo:

UIAlertView

Editado: Lo sentimos, no vio acerca de desaparecer por sí mismo. Creo que necesita una confirmación por parte de los usuarios de los mensajes recibidos. UIAlertView logra bastante eso. No estoy seguro de si se desvanece gradualmente a menos que esté en una aplicación con una vista que tiene un temporizador o un retraso basado en eventos que mostrará una vista y luego la eliminará.

Segunda edición: Encontré una forma de implementarlo. Puede llamar manualmente a la función de descartar después de un tiempo establecido que ha designado. (Lo siento por el puesto desordenado) Se vería algo como esto:

//Create UIAlertView alert 
alert = [[UIAlertView alloc] initWithTitle:@"Title" message:@"Some message" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles: nil]; 

//After some time 
[alert dismissWithClickedButtonIndex:0 animated:TRUE]; 
+0

he implementado algo rápido y sucio utilizando un UIAlertView sin botones. Lo descarto después de un retraso. Funciona, pero no se parece ni cerca de lo que describí. Si no está integrado en la plataforma, debe haber una implementación en alguna parte. No parece demasiado difícil de implementar por su cuenta, pero parece que alguien ya debería haberlo hecho. La aplicación 'FeeddlerRSS' utiliza algo parecido constantemente. – David

+0

Encontré una publicación para otra pregunta similar. Creo que esto es más de lo que estás hablando: http://stackoverflow.com/questions/593147/how-to-display-a-progress-indicator-overlay-hud-on-iphone – Kennzo

15

crear una clase que hereda de UIAlertView. En su constructor simplemente llame al [super init] y luego agregue cualquier vista que desee como subvista. Incluso puede diseñar esta vista en Interface Builder. Algo como esto:

- (id)initWithMessage:(NSString *)message dismissAfter:(NSTimeInterval)interval 
{ 
    if ((self = [super init])) 
    { 
    CustomView * customView = [[[CustomView alloc] init] autorelease]; // or load from NIB 
    [self addSubview:customView]; 
    [self performSelector:@selector(dismissAfterDelay) withObject:nil afterDelay:interval]; 
    } 
    return self; 
} 

- (void)dismissAfterDelay 
{ 
    [self dismissWithClickedButtonIndex:0 animated:YES]; 
} 

Para mostrar su punto de vista de alerta a medida solo init, y llaman show al igual que con un habitual UIAlertView.

CustomAlertView * cav = [[CustomAlertView alloc] initWithMessage:@"Doing Something]; 
[cav show]; 
[cav release]; 

Como un agradable efecto secundario, cuando se presente este punto de vista el fondo se oscurece y obtendrá la bonita animación tambaleante para cualquier vista de alertas.

+2

La clase UIAlertView está destinada a ser utilizado tal como es y no admite subclases. La jerarquía de vista para esta clase es privada y no debe modificarse. –

4

que terminó la creación de mi propia clase. No heredó de UIAlertView. Estructura general es,

-(id)initWithText:(NSString *)msg { 
    // Create a view. Put a label, set the msg 
    CALayer *layer = self.layer; 
    layer.cornerRadius = 8.0f; 
    ... 
    self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.8]; 
    [self performSelector:@selector(dismiss:) withObject:nil afterDelay:2.0]; 
    [self setAutoresizesSubviews:FALSE]; 
    return self; 
} 


- (void)dismiss:(id)sender { 
    // Fade out the message and destroy self 
    [UIView animateWithDuration:0.5 
       animations:^ { self.alpha = 0; } 
       completion:^ (BOOL finished) { [self removeFromSuperview]; }]; 
} 
+0

Tenga en cuenta que debe '#importar ' antes de poder acceder a la propiedad cornerRadius de la capa de la vista. –

+0

Hola, he usado este código. Funciona bien. Pero solo carga una vez. No está funcionando cuando textfield se enfoca nuevamente. Alguna solución.? –

8

He creado una tostada Android-Kind, bastante simple, ya que no necesito más funcionalidad en ella por ahora.

Cuando se muestra, se agrega en la parte inferior de la vista de los padres, por lo que si esa es la vista de VC, entonces estará en la parte inferior central del dispositivo.

El marco se autoajusta a la longitud del texto.

Lo usa haciendo: [self.view addSubview: [[ToastAlert alloc] initWithText: @"Sent"]];, se eliminará automáticamente por lo que no es necesario hacer referencia.

No lo he implementado, pero puede crear un método estático para acortar y aclarar las instrucciones, tipo de: [ToastAlert showText: @"Sent" inView: self.view];.

La clase:

ToastAlert.h

@interface ToastAlert : UILabel { 

} 

- (id)initWithText: (NSString*) msg; 

@end 

ToastAlert.m

#import "ToastAlert.h" 
#import <QuartzCore/QuartzCore.h> 

@implementation ToastAlert 

#define POPUP_DELAY 1.5 

- (id)initWithText: (NSString*) msg 
{ 

    self = [super init]; 
    if (self) { 

     self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7]; 
     self.textColor = [UIColor colorWithWhite:1 alpha: 0.95]; 
     self.font = [UIFont fontWithName: @"Helvetica-Bold" size: 13]; 
     self.text = msg; 
     self.numberOfLines = 0; 
     self.textAlignment = UITextAlignmentCenter; 
     self.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; 


    } 
    return self; 
} 

- (void)didMoveToSuperview { 

    UIView* parent = self.superview; 

    if(parent) { 

     CGSize maximumLabelSize = CGSizeMake(300, 200); 
     CGSize expectedLabelSize = [self.text sizeWithFont: self.font constrainedToSize:maximumLabelSize lineBreakMode: NSLineBreakByTruncatingTail]; 

     expectedLabelSize = CGSizeMake(expectedLabelSize.width + 20, expectedLabelSize.height + 10); 

     self.frame = CGRectMake(parent.center.x - expectedLabelSize.width/2, 
           parent.bounds.size.height-expectedLabelSize.height - 10, 
           expectedLabelSize.width, 
           expectedLabelSize.height); 

     CALayer *layer = self.layer; 
     layer.cornerRadius = 4.0f; 

     [self performSelector:@selector(dismiss:) withObject:nil afterDelay:POPUP_DELAY]; 
    } 
} 

- (void)dismiss:(id)sender { 
    // Fade out the message and destroy self 
    [UIView animateWithDuration:0.6 delay:0 options: UIViewAnimationOptionAllowUserInteraction 
        animations:^ { self.alpha = 0; } 
        completion:^ (BOOL finished) { [self removeFromSuperview]; }]; 
} 

@end 
8

Utilice un UIAlertView con el título nula y los botones nil, entonces se descarta cuando se desee . Así es como lo hice:

Crear una variable de instancia para la vista alerta en su archivo .h:

@interface StatusMessageController : UIViewController { 
    UIAlertView *statusAlert; 
} 

En el archivo .m, crear un método para mostrar la vista de alertas e iniciar un temporizador, y otro para manejar cuando expira el temporizador para descartar la alerta:

- (void)showStatus:(NSString *)message timeout:(double)timeout { 
    statusAlert = [[UIAlertView alloc] initWithTitle:nil 
                message:message 
                delegate:nil 
              cancelButtonTitle:nil 
              otherButtonTitles:nil]; 
    [statusAlert show]; 
    [NSTimer scheduledTimerWithTimeInterval:timeout 
            target:self 
            selector:@selector(timerExpired:) 
            userInfo:nil 
            repeats:NO]; 
} 

- (void)timerExpired:(NSTimer *)timer { 
    [statusAlert dismissWithClickedButtonIndex:0 animated:YES]; 
} 

Cada vez que desee mostrar el mensaje de estado, invocarlo:

[self showStatus:@"Computing" timeout:4.5]; 

En cualquier momento, también se puede descartar la alerta con:

[statusAlert dismissWithClickedButtonIndex:0 animated:YES]; 

También puede cambiar el mensaje en la marcha con la nueva condición:

statusAlert.message = @"Looking up user"; 
+0

funciona a la perfección, gracias! – marimaf

2

respuesta similar a @ de Marco-Mustapic , pero sin herencia.

- (void)dismissAlert:(UIAlertView *)alertView 
{ 
    [alertView dismissWithClickedButtonIndex:0 animated:YES]; 
} 

- (void)showPopupWithTitle:(NSString *)title 
        mesage:(NSString *)message 
       dismissAfter:(NSTimeInterval)interval 
{ 
    UIAlertView *alertView = [[UIAlertView alloc] 
      initWithTitle:title 
       message:message 
       delegate:nil 
     cancelButtonTitle:nil 
     otherButtonTitles:nil 
    ]; 
    [alertView show]; 
    [self performSelector:@selector(dismissAlert:) 
       withObject:alertView 
       afterDelay:interval 
    ]; 
} 

utilizarlo:

[self showPopupWithTitle:@"Hi" message:@"I like pie" dismissAfter:2.0]; 

arrojarlo a una categoría en NSObject o algo para tener siempre a su alrededor.

+0

Me gusta esto. Solo bien. –

2

* Swift 2.2 Respuesta:

func showPopupWithTitle(title: String, message: String, interval: NSTimeInterval) { 
    let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert) 
    presentViewController(alertController, animated: true, completion: nil) 
    self.performSelector(#selector(dismissAlertViewController), withObject: alertController, afterDelay: interval) 
} 

func dismissAlertViewController(alertController: UIAlertController) { 
    alertController.dismissViewControllerAnimated(true, completion: nil) 
} 

showPopupWithTitle("Title", message: "Message", interval: 0.5) 
1

Esto es sólo una versión Swift 3 de user2234810 versión 2.2.

func showPopupWithTitle(title: String, message: String, interval: TimeInterval) { 
    let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) 
    present(alertController, animated: true, completion: nil) 
    self.perform(#selector(dismissAlertViewController), with: alertController, afterDelay: interval) 
} 

func dismissAlertViewController(alertController: UIAlertController) { 
    alertController.dismiss(animated: true, completion: nil) 
} 
showPopupWithTitle(title: "Title", message: "Message", interval: 0.5) 
0

Puede usar mi propio marco StatusAlert escrita en Swift. Le da la capacidad de mostrar alertas similares a las del sistema de Apple y también presentar la misma alerta sin una imagen, título o mensaje en ningún lugar en UIView.

Está disponible a través de Cocoapods y Cartago y es compatible con iPhone X, diseño de Áreas seguras, iPads y permite algunas personalizaciones.

StatusAlertExample application screenshow

Cuestiones relacionadas