2010-08-19 6 views
48

He hecho la aplicación de Android hace unos meses. La clase Toast es muy útil para mí. No necesito considerar el hilo principal y el lugar para mostrarlo. En cualquier lugar que pueda mostrarlo, simplemente lo dejo y desaparecerá automáticamente.¿Cuál es el equivalente de android.widget.Toast para las aplicaciones de iOS?

Toast.makeToast(context, msg, Toast.LENGTH_SHORT).show(); 

Eso es todo. ^^

¿Qué pasa con el iPhone? ¿Hay algo así como la tostada? Solo muestre el mensaje y no necesita preocuparse por eso. Se desaparecerá automáticamente.

+0

teniendo en cuenta que sólo con iOS 4 aplicaciones de fondo permitidos , no había una necesidad previa para tal característica. Sin duda alguien hará una, pero no estoy familiarizado con nada parecido. –

+3

@StephenFurlani, aunque no es obvio de inmediato, los mensajes de brindis también son útiles y ampliamente utilizados en aplicaciones de primer plano. –

+1

@DanielS. De todo corazón estoy de acuerdo. Sin embargo, el OP tiene casi 4 años. En este punto hay algunas características EXCELENTES con iOS 8 con respecto a 'UIPopoverPresentationController's y' passthroughViews' –

Respuesta

4

No existe una clase "lista para usar" en UIKit para hacer esto. Pero es bastante fácil crear una clase que ofrezca este comportamiento.

Solo tiene que crear una clase que herede de UIView. Esta clase tendrá la responsabilidad de - para crear lo que desea visualizar, - para agregarse en la jerarquía de vista principal - para descartarse utilizando un temporizador.

Usted será capaz de utilizarlo como:

[ToastView toastViewInView:myParentView withText:@"what a wonderful text"]; 

Saludos, Quentin

+15

¿Ningún ejemplo de código? Usted solo sugirió que una API para un brindis debería funcionar. –

+14

Tengo una solución mejor, simplemente codifique algo como: import ProjectGenerator miracle.insertFinishedProject() ... debería funcionar. – Josh

+0

Puede encontrar un ejemplo de código a continuación en este hilo. Gracias @Scarmysun – Quentin

70

he estado escribiendo para Android desde hace mucho tiempo y me falta la tostada. Implementé uno. Necesita código? aquí están:

ToastView.h

#import <UIKit/UIKit.h> 

@interface ToastView : UIView 

@property (strong, nonatomic) NSString *text; 

+ (void)showToastInParentView: (UIView *)parentView withText:(NSString *)text withDuaration:(float)duration; 

@end 

ToastView.m

#import "ToastView.h" 

@interface ToastView() 
@property (strong, nonatomic, readonly) UILabel *textLabel; 
@end 
@implementation ToastView 
@synthesize textLabel = _textLabel; 

float const ToastHeight = 50.0f; 
float const ToastGap = 10.0f; 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code 
    } 
    return self; 
} 

-(UILabel *)textLabel 
{ 
    if (!_textLabel) { 
     _textLabel = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 5.0, self.frame.size.width - 10.0, self.frame.size.height - 10.0)]; 
     _textLabel.backgroundColor = [UIColor clearColor]; 
     _textLabel.textAlignment = NSTextAlignmentCenter; 
     _textLabel.textColor = [UIColor whiteColor]; 
     _textLabel.numberOfLines = 2; 
     _textLabel.font = [UIFont systemFontOfSize:13.0]; 
     _textLabel.lineBreakMode = NSLineBreakByCharWrapping; 
     [self addSubview:_textLabel]; 

    } 
    return _textLabel; 
} 

- (void)setText:(NSString *)text 
{ 
    _text = text; 
    self.textLabel.text = text; 
} 

+ (void)showToastInParentView: (UIView *)parentView withText:(NSString *)text withDuaration:(float)duration; 
{ 

    //Count toast views are already showing on parent. Made to show several toasts one above another 
    int toastsAlreadyInParent = 0; 
    for (UIView *subView in [parentView subviews]) { 
     if ([subView isKindOfClass:[ToastView class]]) 
     { 
      toastsAlreadyInParent++; 
     } 
    } 

    CGRect parentFrame = parentView.frame; 

    float yOrigin = parentFrame.size.height - (70.0 + ToastHeight * toastsAlreadyInParent + ToastGap * toastsAlreadyInParent); 

    CGRect selfFrame = CGRectMake(parentFrame.origin.x + 20.0, yOrigin, parentFrame.size.width - 40.0, ToastHeight); 
    ToastView *toast = [[ToastView alloc] initWithFrame:selfFrame]; 

    toast.backgroundColor = [UIColor darkGrayColor]; 
    toast.alpha = 0.0f; 
    toast.layer.cornerRadius = 4.0; 
    toast.text = text; 

    [parentView addSubview:toast]; 

    [UIView animateWithDuration:0.4 animations:^{ 
     toast.alpha = 0.9f; 
     toast.textLabel.alpha = 0.9f; 
    }completion:^(BOOL finished) { 
     if(finished){ 

     } 
    }]; 


    [toast performSelector:@selector(hideSelf) withObject:nil afterDelay:duration]; 

} 

- (void)hideSelf 
{ 

    [UIView animateWithDuration:0.4 animations:^{ 
     self.alpha = 0.0; 
     self.textLabel.alpha = 0.0; 
    }completion:^(BOOL finished) { 
     if(finished){ 
      [self removeFromSuperview]; 
     } 
    }]; 
} 

@end 

llamada desde ViewController

[ToastView showToastInParentView:self.view withText:@"What a toast!" withDuaration:5.0]; 
+0

Genial (@Scarmysun: a excepción de los dos puntos adicionales antes del cuerpo de implementación. SO no me deja hacer una edición tan corta, de lo contrario lo habría arreglado ...). Upvoted – JulianSymes

+1

Esto colapsó para mí hasta que cambié el nombre de "setTextLabel:" a otra cosa. "setTextLabel:" se llama automáticamente cada vez que se actualiza la propiedad (ya que una propiedad es solo una abreviatura para usar el getter o setter). Después de hacer ese cambio, funcionó bien. – BeccaP

+0

Buen comentario @BeccaP. He actualizado mi implementación. Ahora la etiqueta de texto es propiedad privada y se crea una instancia de forma perezosa. Se agregó una propiedad pública de "texto". – SSemashko

1

les dejo la versión rápida de la respuesta Scarmysun :) muchas gracias

import Foundation 
import UIKit 

class ToastView: UIView { 
    static let toastHeight:CGFloat = 50.0 
    static let toastGap:CGFloat = 10; 
    lazy var textLabel: UILabel = UILabel(frame: CGRectMake(5.0, 5.0, self.frame.size.width - 10.0, self.frame.size.height - 10.0)) 


    static func showInParent(parentView: UIView!, withText text: String, forDuration duration: double_t) { 

     //Count toast views are already showing on parent. Made to show several toasts one above another 
     var toastsAlreadyInParent = 0; 

     for view in parentView.subviews { 
      if (view.isKindOfClass(ToastView)) { 
       toastsAlreadyInParent++ 
      } 
     } 

     var parentFrame = parentView.frame; 

     var yOrigin = parentFrame.size.height - getDouble(toastsAlreadyInParent) 

     var selfFrame = CGRectMake(parentFrame.origin.x + 20.0, yOrigin, parentFrame.size.width - 40.0, toastHeight); 
     var toast = ToastView(frame: selfFrame) 

     toast.textLabel.backgroundColor = UIColor.clearColor() 
     toast.textLabel.textAlignment = NSTextAlignment.Center 
     toast.textLabel.textColor = UIColor.whiteColor() 
     toast.textLabel.numberOfLines = 2 
     toast.textLabel.font = UIFont.systemFontOfSize(13.0) 
     toast.addSubview(toast.textLabel) 

     toast.backgroundColor = UIColor.darkGrayColor() 
     toast.alpha = 0.0; 
     toast.layer.cornerRadius = 4.0; 
     toast.textLabel.text = text; 

     parentView.addSubview(toast) 
     UIView.animateWithDuration(0.4, animations: { 
      toast.alpha = 0.9 
      toast.textLabel.alpha = 0.9 
     }) 


     toast.performSelector(Selector("hideSelf"), withObject: nil, afterDelay: duration) 

    } 

    static private func getDouble(toastsAlreadyInParent : Int) -> CGFloat { 
     return (70.0 + toastHeight * CGFloat(toastsAlreadyInParent) + toastGap * CGFloat(toastsAlreadyInParent)); 
    } 

    func hideSelf() { 
     UIView.animateWithDuration(0.4, animations: { 
      self.alpha = 0.0 
      self.textLabel.alpha = 0.0 
     }, completion: { t in self.removeFromSuperview() }) 
    } 

} 
2

Editar: Actualización de Swift 3

Aquí hay una versión de Swift 3 basada en wojciech_m la respuesta de aciejewski. Esto se parece más a Android Toast y no acumula tostadas entre sí. Dibuja tostadas en el centro de la pantalla. Puede manejar textos largos de líneas múltiples.

import UIKit 

class ToastView: UIView { 

    private static let hLabelGap: CGFloat = 40.0 
    private static let vLabelGap: CGFloat = 20.0 
    private static let hToastGap: CGFloat = 20.0 
    private static let vToastGap: CGFloat = 10.0 

    private var textLabel: UILabel! 

    static func showInParent(_ parentView: UIView, _ text: String, duration: Double = 3.0) { 
     let labelFrame = CGRect(x: parentView.frame.origin.x + hLabelGap, 
           y: parentView.frame.origin.y + vLabelGap, 
           width: parentView.frame.width - 2 * hLabelGap, 
           height: parentView.frame.height - 2 * vLabelGap) 
     let label = UILabel() 
     label.font = UIFont.systemFont(ofSize: 15.0) 
     label.text = text 
     label.backgroundColor = UIColor.clear 
     label.textAlignment = NSTextAlignment.center 
     label.textColor = UIColor.white 
     label.numberOfLines = 0 
     label.frame = labelFrame 
     label.sizeToFit() 

     let toast = ToastView() 
     toast.textLabel = label 
     toast.addSubview(label) 
     toast.frame = CGRect(x: label.frame.origin.x - hToastGap, 
          y: label.frame.origin.y - vToastGap, 
          width: label.frame.width + 2 * hToastGap, 
          height: label.frame.height + 2 * vToastGap) 
     toast.backgroundColor = UIColor.darkGray 
     toast.alpha = 0.0 
     toast.layer.cornerRadius = 20.0 
     toast.center = parentView.center 
     label.center = CGPoint(x: toast.frame.size.width/2, y: toast.frame.size.height/2) 

     parentView.addSubview(toast) 

     UIView.animate(withDuration: 0.4, animations: { 
      toast.alpha = 0.9 
      label.alpha = 0.9 
     }) 

     toast.perform(#selector(hideSelf), with: nil, afterDelay: duration) 
    } 

    @objc private func hideSelf() { 
     UIView.animate(withDuration: 0.4, animations: { 
      self.alpha = 0.0 
      self.textLabel.alpha = 0.0 
      }, completion: { t in self.removeFromSuperview() }) 
    } 
} 

Uso de otro controlador:

ToastView.showInParent(navigationController!.view, "Hello world") 
0

Usted puede hacer esto de muchas maneras uno de la forma es utilizar UIAlertViewController() en swift3

let alertManager=UIAlertController(title: nil, message: "Welcome!", preferredStyle: .alert) 

self.present(alertManager, animated: true, completion: nil) 

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+1, 
execute: { 
            alertManager.dismiss(animated: false, completion: nil) 

           }) 
Cuestiones relacionadas