web-dev-qa-db-fra.com

Comment afficher un message contextuel temporaire sur iPhone / iPad / iOS

Je voudrais afficher un message temporaire sur l'iPhone/iPad affichant la confirmation d'une action, ou un état rapide sur une activité en arrière-plan.

Existe-t-il un contrôle standard pour ce faire? J'ai vu des applications faire ça. Un rectangle arrondi, sombre et partiellement transparent avec du texte à l'intérieur. Il ne demande pas de saisie utilisateur mais disparaît de lui-même en peu de temps. Android a une construction similaire qui est standard. Également similaire aux fenêtres affichées par Growl.

Suggestions appréciées.

30
David

Il y a une bibliothèque d'utilisateurs sur cocoacontrols.com qui émule les fenêtres pop-up de style Android. Peut-être ce que vous cherchez.

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

Il y a aussi celui-ci qui suit la même idée.

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

16
Joe Masilotti

Créez une classe qui hérite de UIAlertView. Dans votre constructeur, appelez simplement [super init], puis ajoutez la vue que vous souhaitez en tant que sous-vue. Vous pouvez même concevoir cette vue dans Interface Builder. Quelque chose comme ça:

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

Pour afficher votre vue d'alerte personnalisée, il suffit de l'initier et d'appeler show comme avec un UIAlertView normal.

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

Comme effet secondaire de Nice, lorsque vous présentez cette vue, l'arrière-plan s'assombrira et vous obtiendrez l'animation Nice vacillant pour toute vue d'alerte.

15
Marco Mustapic

Utilisez UIAlertView. Voici un lien rapide vers un exemple simple:

IAlertView

Modifié: Désolé, je n'ai pas vu disparaître de lui-même. Je pense que les utilisateurs doivent confirmer les messages reçus. UIAlertView accomplit à peu près cela. Je ne sais pas si vous l'avez progressivement disparu, sauf si vous êtes dans une application avec une vue qui a une minuterie ou un retard basé sur un événement qui affichera une vue, puis la supprimera finalement.

Deuxième édition: a trouvé un moyen de l'implémenter. Vous pouvez appeler manuellement la fonction de suppression après un certain temps défini que vous avez désigné. (Désolé pour le message en désordre) Il ressemblerait à ceci:

//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];
9
Kennzo

Utilisez un UIAlertView avec un titre nul et des boutons nil, puis supprimez-le lorsque vous le souhaitez. Voici comment j'ai fait ça:

Créez une variable d'instance pour la vue d'alerte dans votre fichier .h:

@interface StatusMessageController : UIViewController {
    UIAlertView *statusAlert;
}

Dans votre fichier .m, créez une méthode pour afficher la vue d'alerte et démarrer une minuterie, et une autre pour gérer lorsque la minuterie expire pour ignorer l'alerte:

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

Chaque fois que vous souhaitez afficher le message d'état, invoquez-le:

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

À tout moment, vous pouvez également ignorer l'alerte avec:

[statusAlert dismissWithClickedButtonIndex:0 animated:YES];

Vous pouvez également modifier le message à la volée avec un nouveau statut:

statusAlert.message = @"Looking up user";
8
async8192

J'ai créé un toast de type Android, assez simple car je n'ai pas besoin de plus de fonctionnalités pour l'instant.

Quand il est affiché, il est ajouté en bas de la vue du parent, donc si cette vue est la vue du VC, elle se trouvera en bas au centre de l'appareil.

Le cadre est automatiquement ajusté à la longueur du texte.

Vous l'utilisez en faisant: [self.view addSubview: [[ToastAlert alloc] initWithText: @"Sent"]];, il sera automatiquement supprimé, aucune référence n'est donc nécessaire.

Je n'ai pas implémenté cela, mais vous pouvez créer une méthode statique pour raccourcir et clarifier l'instruction, en quelque sorte: [ToastAlert showText: @"Sent" inView: self.view];.

La classe:

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
htafoya

J'ai fini par créer ma propre classe. N'a pas hérité de UIAlertView. La structure générale est,

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

Réponse similaire à @ marco-mustapic, mais sans héritage.

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

Pour l'utiliser:

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

Jetez-le dans une catégorie sur NSObject ou quelque chose pour l'avoir toujours autour.

2
theory

* Swift 2.2 Answer:

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)
2
user2234810

Ceci est juste une version Swift de user2234810 2.2 version.

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)
2
Micah Montoya

Vous pouvez utiliser mon propre StatusAlert framework écrit en Swift. Il vous donne la possibilité d'afficher Apple alerte de type système ainsi que de présenter la même alerte sans image, titre ou message n'importe où dans UIView.

Il est disponible via Cocoapods et Carthage et prend en charge l'iPhone X, la disposition des zones de sécurité, les iPads et permet certaines personnalisations.

StatusAlertExample application screenshow

1
LowKostKustomz