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.
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.
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.
Utilisez UIAlertView. Voici un lien rapide vers un exemple simple:
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];
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";
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
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]; }];
}
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.
* 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)
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)
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.