Exibindo uma mensagem no iOS que tem a mesma funcionalidade do Toast no Android

121

Preciso saber se existe algum método no iOS que se comporta como mensagens de brinde no Android. Ou seja, preciso exibir uma mensagem que é descartada automaticamente após alguns segundos. Isso é semelhante à funcionalidade da classe Toast no ambiente Android.

Nilesh Kumar
fonte
1
Você pode querer verificar este link stackoverflow.com/questions/3522866/android-toast-in-iphone
Emmanuel
Obrigado Emmanuel pelo link. Estou tentando implementá-lo
Nilesh Kumar
Você pode verificar este github.com/ecstasy2/toast-notifications-ios
Rahul
Esse cara forneceu a solução stackoverflow.com/questions/3522866/…
user3556406
Uma boa lib: github.com/scalessec/Toast-Swift
Ferran Maylinch

Respostas:

99

Você pode fazer uso do MBProgressHUDprojeto.

Use o modo HUD MBProgressHUDModeTextpara um comportamento semelhante ao brinde,

MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];

// Configure for text only and offset down
hud.mode = MBProgressHUDModeText;
hud.label.text = @"Some message...";
hud.margin = 10.f;
hud.yOffset = 150.f;
hud.removeFromSuperViewOnHide = YES;

[hud hideAnimated:YES afterDelay:3];

insira a descrição da imagem aqui

Amar
fonte
1
Para um comportamento 100% semelhante ao do Android, sugiro configurar de hud.isUserInteractionEnabled = falseforma que você possa interagir com o resto do aplicativo enquanto a mensagem é exibida.
Mattia C.
@MattiaC. Não consigo definir o valor para hud.isUserInteractionEnabled = falseaparências como apenas getter é fornecido.
Aniket Thakur
está bloqueando a IU. não é o mesmo comportamento do Android
Roman M,
Use hud.offset = CGPoint(x: 0, y: MBProgressMaxOffset)para posicionar o HUD na borda inferior.
ElegyD
86
NSString *message = @"Some message...";

UIAlertView *toast = [[UIAlertView alloc] initWithTitle:nil
                                                message:message
                                               delegate:nil
                                      cancelButtonTitle:nil
                                      otherButtonTitles:nil, nil];
[toast show];

int duration = 1; // duration in seconds

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    [toast dismissWithClickedButtonIndex:0 animated:YES];
});

Usando UIAlertViewController para iOS 9 ou posterior

NSString *message = @"Some message...";

UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
                                                               message:message
                                                        preferredStyle:UIAlertControllerStyleAlert];

[self presentViewController:alert animated:YES completion:nil];

int duration = 1; // duration in seconds

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    [alert dismissViewControllerAnimated:YES completion:nil];
});

Swift 3.2

let message = "Some message..."
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
self.present(alert, animated: true)

// duration in seconds
let duration: Double = 5

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + duration) {
    alert.dismiss(animated: true)
}
Kirit Vaghela
fonte
7
Isso não é exatamente o mesmo que brinde - a interação do usuário com outras visualizações é desabilitada enquanto a caixa de diálogo é exibida. Talvez haja uma maneira de remover o fundo "esmaecido" com a adição da capacidade de interagir com outras visualizações na tela (como botões ou tela de pintura no meu caso por trás do alerta)?
vir nos
UIAlertView tornou-se obsoleto no iOS9. Existe alguma maneira alternativa de fazer isso?
Rajeev Bhatia
obrigado, mas eu poderia usar o UIAlertController para exibir o toast também?
Rajeev Bhatia
50

No Android, um Toast é uma mensagem curta que é exibida na tela por um curto período de tempo e, em seguida, desaparece automaticamente sem interromper a interação do usuário com o aplicativo.

insira a descrição da imagem aqui

Portanto, muitas pessoas com experiência no Android querem saber o que é a versão iOS de um Toast. Além da questão atual, outras questões semelhantes podem ser encontradas aqui , aqui e aqui . A resposta é que não há equivalente exato a um Toast no iOS . Várias soluções alternativas que foram apresentadas, no entanto, incluindo

  • fazendo sua própria torrada com um UIView(veja aqui , aqui , aqui e aqui )
  • importar um projeto de terceiros que imita um Toast (veja aqui , aqui , aqui e aqui )
  • usando um alerta sem botão com um cronômetro (veja aqui )

No entanto, meu conselho é manter as opções de IU padrão que já vêm com o iOS. Não tente fazer seu aplicativo parecer e se comportar exatamente da mesma forma que a versão do Android. Pense em como reembalá-lo para que tenha a aparência de um aplicativo iOS. Veja o link a seguir para algumas opções.

Considere redesenhar a IU de uma forma que transmita as mesmas informações. Ou, se a informação for muito importante, um Alerta pode ser a resposta.

Suragch
fonte
Muito bem colocado, especialmente a noção de retrabalhar a IU. Definitivamente não é a resposta mais simples para desenvolvedores ou designers, mas Brindes podem facilmente se tornar outra "gaveta de lixo" de UX móvel, muitas vezes usada como um depósito de conteúdo que 1) é falador e distrai, ou 2) é uma informação genuinamente útil, e , como tal, seria melhor apresentado no contexto direto com os elementos de conteúdo principal do aplicativo como um emblema, ícone ou mensagem de status sequencial.
macserv
27

Swift 4

Que tal este pequeno truque?

func showToast(controller: UIViewController, message : String, seconds: Double) {
    let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
    alert.view.backgroundColor = UIColor.black
    alert.view.alpha = 0.6
    alert.view.layer.cornerRadius = 15

    controller.present(alert, animated: true)

    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + seconds) {
        alert.dismiss(animated: true)
    }
}

Exemplo de chamada:

showToast(controller: self, message : "This is a test", seconds: 2.0)

Resultado:

Sazzad Hissain Khan
fonte
2
Parece incrível. Obrigado!
Zeero0
@decades qual era o problema?
Sazzad Hissain Khan
1
Olá Sazzad, o problema era obviamente que ele requer um NavigationController. Eu só estava tentando trazer isso à tona. Talvez meu comentário esteja errado e obsoleto
décadas de
feliz em saber que você consertou
Sazzad Hissain Khan
1
Muito obrigado, solução muito precisa
Sakthimuthiah
21

Swift 3

Para uma solução simples sem código de terceiros:

insira a descrição da imagem aqui

Basta usar um UIAlertController normal, mas com style = actionSheet (veja o código abaixo)

let alertDisapperTimeInSeconds = 2.0
let alert = UIAlertController(title: nil, message: "Toast!", preferredStyle: .actionSheet)
self.present(alert, animated: true)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + alertDisapperTimeInSeconds) {
  alert.dismiss(animated: true)
}

A vantagem desta solução:

  1. Android como mensagem de brinde
  2. Ainda aparência e comportamento iOS
GedankenNebel
fonte
2
Muito inteligente. Eu nunca teria pensado nisso, obrigado: D
Maksym Musiienko
5

Para Swift 3 e 4 :

Use a biblioteca Toaster

Toast(text: "Hello, world!", duration: Delay.long)

insira a descrição da imagem aqui

Para Swift 2 :

Use JLToast

Hamed Ghadirian
fonte
4

Se você quiser um com estilo iOS, baixe este framework do Github

Estrutura do iOS Toast Alert View

Estes exemplos funcionam em seu UIViewController, uma vez que você importou o Framework.

Exemplo 1:

//Manual 
let tav = ToastAlertView()
tav.message = "Hey!"
tav.image = UIImage(named: "img1")!
tav.show()
//tav.dismiss() to Hide

Exemplo 2:

//Toast Alert View with Time Dissmis Only
self.showToastAlert("5 Seconds",
                image: UIImage(named: "img1")!,
                hideWithTap: false,
                hideWithTime: true,
                hideTime: 5.0)

Final:

Exemplo de imagem de visualização de alerta do brinde

Eduardo irias
fonte
4

Swift 4.0:

Faça um novo arquivo rápido. (Arquivo-Novo-Arquivo-Esvaziar Arquivo Swift). Nomeie-o UIViewToast.Add o seguinte código.

import UIKit

func /(lhs: CGFloat, rhs: Int) -> CGFloat {
return lhs / CGFloat(rhs)
}

let HRToastDefaultDuration  =   2.0
let HRToastFadeDuration     =   0.2
let HRToastHorizontalMargin : CGFloat  =   10.0
let HRToastVerticalMargin   : CGFloat  =   10.0

let HRToastPositionDefault  =   "bottom"
let HRToastPositionTop      =   "top"
let HRToastPositionCenter   =   "center"

// activity
let HRToastActivityWidth  :  CGFloat  = 100.0
let HRToastActivityHeight :  CGFloat  = 100.0
let HRToastActivityPositionDefault    = "center"

// image size
let HRToastImageViewWidth :  CGFloat  = 80.0
let HRToastImageViewHeight:  CGFloat  = 80.0

// label setting
let HRToastMaxWidth       :  CGFloat  = 0.8;      // 80% of parent view width
let HRToastMaxHeight      :  CGFloat  = 0.8;
let HRToastFontSize       :  CGFloat  = 16.0
let HRToastMaxTitleLines              = 0
let HRToastMaxMessageLines            = 0

// shadow appearance
let HRToastShadowOpacity  : CGFloat   = 0.8
let HRToastShadowRadius   : CGFloat   = 6.0
let HRToastShadowOffset   : CGSize    = CGSize(width: 4.0, height: 4.0)

let HRToastOpacity        : CGFloat   = 0.5
let HRToastCornerRadius   : CGFloat   = 10.0

var HRToastActivityView: UnsafePointer<UIView>?
var HRToastTimer: UnsafePointer<Timer>?
var HRToastView: UnsafePointer<UIView>?


// Color Scheme
let HRAppColor:UIColor = UIColor.black//UIappViewController().appUIColor
let HRAppColor_2:UIColor = UIColor.white


let HRToastHidesOnTap       =   true
let HRToastDisplayShadow    =   false

//HRToast (UIView + Toast using Swift)

extension UIView {

//public methods
func makeToast(message msg: String) {
    self.makeToast(message: msg, duration: HRToastDefaultDuration, position: HRToastPositionDefault as AnyObject)
}

func makeToast(message msg: String, duration: Double, position: AnyObject) {
    let toast = self.viewForMessage(msg: msg, title: nil, image: nil)
    self.showToast(toast: toast!, duration: duration, position: position)
}

func makeToast(message msg: String, duration: Double, position: AnyObject, title: String) {
    let toast = self.viewForMessage(msg: msg, title: title, image: nil)
    self.showToast(toast: toast!, duration: duration, position: position)
}

func makeToast(message msg: String, duration: Double, position: AnyObject, image: UIImage) {
    let toast = self.viewForMessage(msg: msg, title: nil, image: image)
    self.showToast(toast: toast!, duration: duration, position: position)
}

func makeToast(message msg: String, duration: Double, position: AnyObject, title: String, image: UIImage) {
    let toast = self.viewForMessage(msg: msg, title: title, image: image)
    self.showToast(toast: toast!, duration: duration, position: position)
}

func showToast(toast: UIView) {
    self.showToast(toast: toast, duration: HRToastDefaultDuration, position: HRToastPositionDefault as AnyObject)
}

func showToast(toast: UIView, duration: Double, position: AnyObject) {
    let existToast = objc_getAssociatedObject(self, &HRToastView) as! UIView?
    if existToast != nil {
        if let timer: Timer = objc_getAssociatedObject(existToast!, &HRToastTimer) as? Timer {
            timer.invalidate();
        }
        self.hideToast(toast: existToast!, force: false);
    }

    toast.center = self.centerPointForPosition(position: position, toast: toast)
    toast.alpha = 0.0

    if HRToastHidesOnTap {
        let tapRecognizer = UITapGestureRecognizer(target: toast, action: #selector(handleToastTapped(recognizer:)))
        toast.addGestureRecognizer(tapRecognizer)
        toast.isUserInteractionEnabled = true;
        toast.isExclusiveTouch = true;
    }

    self.addSubview(toast)
    objc_setAssociatedObject(self, &HRToastView, toast, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)

    UIView.animate(withDuration: HRToastFadeDuration,
                               delay: 0.0, options: ([.curveEaseOut, .allowUserInteraction]),
                               animations: {
                                toast.alpha = 1.0
    },
                               completion: { (finished: Bool) in
                                let timer = Timer.scheduledTimer(timeInterval: duration, target: self, selector: #selector(self.toastTimerDidFinish(timer:)), userInfo: toast, repeats: false)
                                objc_setAssociatedObject(toast, &HRToastTimer, timer, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    })
}

func makeToastActivity() {
    self.makeToastActivity(position: HRToastActivityPositionDefault as AnyObject)
}

func showToastActivity() {
    self.isUserInteractionEnabled = false
    self.makeToastActivity()
}

func removeToastActivity() {
    self.isUserInteractionEnabled = true
    self.hideToastActivity()

}

func makeToastActivityWithMessage(message msg: String){
    self.makeToastActivity(position: HRToastActivityPositionDefault as AnyObject, message: msg)
}
func makeToastActivityWithMessage(message msg: String,addOverlay: Bool){

    self.makeToastActivity(position: HRToastActivityPositionDefault as AnyObject, message: msg,addOverlay: true)
}

func makeToastActivity(position pos: AnyObject, message msg: String = "",addOverlay overlay: Bool = false) {
    let existingActivityView: UIView? = objc_getAssociatedObject(self, &HRToastActivityView) as? UIView
    if existingActivityView != nil { return }

    let activityView = UIView(frame: CGRect(x:0, y:0, width: self.frame.width, height: self.frame.height))
    activityView.center = self.centerPointForPosition(position: pos, toast: activityView)
    activityView.alpha = 0.0
    activityView.autoresizingMask = ([.flexibleLeftMargin, .flexibleTopMargin, .flexibleRightMargin, .flexibleBottomMargin])
    activityView.layer.cornerRadius = HRToastCornerRadius

    if HRToastDisplayShadow {
        activityView.layer.shadowColor = UIColor.black.cgColor
        activityView.layer.shadowOpacity = Float(HRToastShadowOpacity)
        activityView.layer.shadowRadius = HRToastShadowRadius
        activityView.layer.shadowOffset = HRToastShadowOffset
    }

    let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)
    activityIndicatorView.center = CGPoint(x:activityView.bounds.size.width / 2, y: activityView.bounds.size.height / 2)
    activityIndicatorView.color = HRAppColor
    activityView.addSubview(activityIndicatorView)
    activityIndicatorView.startAnimating()

    if (!msg.isEmpty){
        activityIndicatorView.frame.origin.y -= 10



        let activityMessageLabel = UILabel(frame: CGRect(x: activityView.bounds.origin.x, y: (activityIndicatorView.frame.origin.y + activityIndicatorView.frame.size.height + 10), width: activityView.bounds.size.width, height: 20))
        activityMessageLabel.textColor = UIColor.white
        activityMessageLabel.font = (msg.count<=10) ? UIFont(name:activityMessageLabel.font.fontName, size: 16) : UIFont(name:activityMessageLabel.font.fontName, size: 16)
        activityMessageLabel.textAlignment = .center
        activityMessageLabel.text = msg + ".."
        if overlay {
            activityMessageLabel.textColor = UIColor.white
            activityView.backgroundColor = HRAppColor.withAlphaComponent(HRToastOpacity)
            activityIndicatorView.color = UIColor.white
        }
        else {
            activityMessageLabel.textColor = HRAppColor
            activityView.backgroundColor = UIColor.clear
            activityIndicatorView.color = HRAppColor
        }

        activityView.addSubview(activityMessageLabel)

    }

    self.addSubview(activityView)

    // associate activity view with self
    objc_setAssociatedObject(self, &HRToastActivityView, activityView, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)

    UIView.animate(withDuration: HRToastFadeDuration,
                               delay: 0.0,
                               options: UIViewAnimationOptions.curveEaseOut,
                               animations: {
                                activityView.alpha = 1.0
    },
                               completion: nil)
    self.isUserInteractionEnabled = false
}

func hideToastActivity() {
    self.isUserInteractionEnabled = true
    let existingActivityView = objc_getAssociatedObject(self, &HRToastActivityView) as! UIView?
    if existingActivityView == nil { return }
    UIView.animate(withDuration: HRToastFadeDuration,
                               delay: 0.0,
                               options: UIViewAnimationOptions.curveEaseOut,
                               animations: {
                                existingActivityView!.alpha = 0.0
    },
                               completion: { (finished: Bool) in
                                existingActivityView!.removeFromSuperview()
                                objc_setAssociatedObject(self, &HRToastActivityView, nil, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    })
}

/*
 *  private methods (helper)
 */
func hideToast(toast: UIView) {
    self.isUserInteractionEnabled = true
    self.hideToast(toast: toast, force: false);
}

func hideToast(toast: UIView, force: Bool) {
    let completeClosure = { (finish: Bool) -> () in
        toast.removeFromSuperview()
        objc_setAssociatedObject(self, &HRToastTimer, nil, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }

    if force {
        completeClosure(true)
    } else {
        UIView.animate(withDuration: HRToastFadeDuration,
                                   delay: 0.0,
                                   options: ([.curveEaseIn, .beginFromCurrentState]),
                                   animations: {
                                    toast.alpha = 0.0
        },
                                   completion:completeClosure)
    }
}

@objc func toastTimerDidFinish(timer: Timer) {
    self.hideToast(toast: timer.userInfo as! UIView)
}

@objc func handleToastTapped(recognizer: UITapGestureRecognizer) {

    // var timer = objc_getAssociatedObject(self, &HRToastTimer) as! NSTimer
    // timer.invalidate()

    self.hideToast(toast: recognizer.view!)
}

func centerPointForPosition(position: AnyObject, toast: UIView) -> CGPoint {
    if position is String {
        let toastSize = toast.bounds.size
        let viewSize  = self.bounds.size
        if position.lowercased == HRToastPositionTop {
            return CGPoint(x: viewSize.width/2, y: toastSize.height/2 + HRToastVerticalMargin)

        } else if position.lowercased == HRToastPositionDefault {
            return CGPoint(x:viewSize.width/2, y:viewSize.height - toastSize.height - 15 - HRToastVerticalMargin)
        } else if position.lowercased == HRToastPositionCenter {
            return CGPoint(x:viewSize.width/2, y:viewSize.height/2)
        }
    } else if position is NSValue {
        return position.cgPointValue
    }

    print("Warning: Invalid position for toast.")
    return self.centerPointForPosition(position: HRToastPositionDefault as AnyObject, toast: toast)
}

func viewForMessage(msg: String?, title: String?, image: UIImage?) -> UIView? {
    if msg == nil && title == nil && image == nil { return nil }

    var msgLabel: UILabel?
    var titleLabel: UILabel?
    var imageView: UIImageView?

    let wrapperView = UIView()
    wrapperView.autoresizingMask = ([.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin])
    wrapperView.layer.cornerRadius = HRToastCornerRadius
    wrapperView.backgroundColor = UIColor.black.withAlphaComponent(HRToastOpacity)

    if HRToastDisplayShadow {
        wrapperView.layer.shadowColor = UIColor.black.cgColor
        wrapperView.layer.shadowOpacity = Float(HRToastShadowOpacity)
        wrapperView.layer.shadowRadius = HRToastShadowRadius
        wrapperView.layer.shadowOffset = HRToastShadowOffset
    }

    if image != nil {
        imageView = UIImageView(image: image)
        imageView!.contentMode = .scaleAspectFit
        imageView!.frame = CGRect(x:HRToastHorizontalMargin, y: HRToastVerticalMargin, width: CGFloat(HRToastImageViewWidth), height: CGFloat(HRToastImageViewHeight))
    }

    var imageWidth: CGFloat, imageHeight: CGFloat, imageLeft: CGFloat
    if imageView != nil {
        imageWidth = imageView!.bounds.size.width
        imageHeight = imageView!.bounds.size.height
        imageLeft = HRToastHorizontalMargin
    } else {
        imageWidth  = 0.0; imageHeight = 0.0; imageLeft   = 0.0
    }

    if title != nil {
        titleLabel = UILabel()
        titleLabel!.numberOfLines = HRToastMaxTitleLines
        titleLabel!.font = UIFont.boldSystemFont(ofSize: HRToastFontSize)
        titleLabel!.textAlignment = .center
        titleLabel!.lineBreakMode = .byWordWrapping
        titleLabel!.textColor = UIColor.white
        titleLabel!.backgroundColor = UIColor.clear
        titleLabel!.alpha = 1.0
        titleLabel!.text = title

        // size the title label according to the length of the text

        let maxSizeTitle = CGSize(width: (self.bounds.size.width * HRToastMaxWidth) - imageWidth, height: self.bounds.size.height * HRToastMaxHeight)

        let expectedHeight = title!.stringHeightWithFontSize(fontSize: HRToastFontSize, width: maxSizeTitle.width)
        titleLabel!.frame = CGRect(x: 0.0, y: 0.0, width: maxSizeTitle.width, height: expectedHeight)
    }

    if msg != nil {
        msgLabel = UILabel();
        msgLabel!.numberOfLines = HRToastMaxMessageLines
        msgLabel!.font = UIFont.systemFont(ofSize: HRToastFontSize)
        msgLabel!.lineBreakMode = .byWordWrapping
        msgLabel!.textAlignment = .center
        msgLabel!.textColor = UIColor.white
        msgLabel!.backgroundColor = UIColor.clear
        msgLabel!.alpha = 1.0
        msgLabel!.text = msg


        let maxSizeMessage = CGSize(width: (self.bounds.size.width * HRToastMaxWidth) - imageWidth, height: self.bounds.size.height * HRToastMaxHeight)
        let expectedHeight = msg!.stringHeightWithFontSize(fontSize: HRToastFontSize, width: maxSizeMessage.width)
        msgLabel!.frame = CGRect(x: 0.0, y: 0.0, width: maxSizeMessage.width, height: expectedHeight)
    }

    var titleWidth: CGFloat, titleHeight: CGFloat, titleTop: CGFloat, titleLeft: CGFloat
    if titleLabel != nil {
        titleWidth = titleLabel!.bounds.size.width
        titleHeight = titleLabel!.bounds.size.height
        titleTop = HRToastVerticalMargin
        titleLeft = imageLeft + imageWidth + HRToastHorizontalMargin
    } else {
        titleWidth = 0.0; titleHeight = 0.0; titleTop = 0.0; titleLeft = 0.0
    }

    var msgWidth: CGFloat, msgHeight: CGFloat, msgTop: CGFloat, msgLeft: CGFloat
    if msgLabel != nil {
        msgWidth = msgLabel!.bounds.size.width
        msgHeight = msgLabel!.bounds.size.height
        msgTop = titleTop + titleHeight + HRToastVerticalMargin
        msgLeft = imageLeft + imageWidth + HRToastHorizontalMargin
    } else {
        msgWidth = 0.0; msgHeight = 0.0; msgTop = 0.0; msgLeft = 0.0
    }

    let largerWidth = max(titleWidth, msgWidth)
    let largerLeft  = max(titleLeft, msgLeft)

    // set wrapper view's frame
    let wrapperWidth  = max(imageWidth + HRToastHorizontalMargin * 2, largerLeft + largerWidth + HRToastHorizontalMargin)
    let wrapperHeight = max(msgTop + msgHeight + HRToastVerticalMargin, imageHeight + HRToastVerticalMargin * 2)
    wrapperView.frame = CGRect(x: 0.0, y: 0.0, width: wrapperWidth, height: wrapperHeight)

    // add subviews
    if titleLabel != nil {
        titleLabel!.frame = CGRect(x: titleLeft, y: titleTop, width: titleWidth, height: titleHeight)
        wrapperView.addSubview(titleLabel!)
    }
    if msgLabel != nil {
        msgLabel!.frame = CGRect(x: msgLeft, y: msgTop, width: msgWidth, height: msgHeight)
        wrapperView.addSubview(msgLabel!)
    }
    if imageView != nil {
        wrapperView.addSubview(imageView!)
    }

    return wrapperView
    }

    }

extension String {

func stringHeightWithFontSize(fontSize: CGFloat,width: CGFloat) -> CGFloat {
    let font = UIFont.systemFont(ofSize: fontSize)
    let size = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineBreakMode = .byWordWrapping;
    let attributes = [NSAttributedStringKey.font:font,
                      NSAttributedStringKey.paragraphStyle:paragraphStyle.copy()]

    let text = self as NSString
    let rect = text.boundingRect(with: size, options:.usesLineFragmentOrigin, attributes: attributes, context:nil)
    return rect.size.height
}
}

Uso:

  self.view.makeToast(message: "Simple Toast")
  self.view.makeToast(message: "Simple Toast", duration: 2.0, position:HRToastPositionTop)

  self.view.makeToast(message: "Simple Toast", duration: 2.0, position: HRToastPositionCenter, image: UIImage(named: "ic_120x120")!)

  self.view.makeToast(message: "It is just awesome", duration: 2.0, position: HRToastPositionDefault, title: "Simple Toast")

  self.view.makeToast(message: "It is just awesome", duration: 2.0, position: HRToastPositionCenter, title: "Simple Toast", image: UIImage(named: "ic_120x120")!)

  self.view.makeToastActivity()
  self.view.makeToastActivity(position: HRToastPositionCenter)
  self.view.makeToastActivity(position: HRToastPositionDefault, message: "Loading")
  self.view.makeToastActivityWithMessage(message: "Loading")

  // Hide Toast
  self.view.hideToast(toast: self.view)
  self.view.hideToast(toast: self.view, force: true)
  self.view.hideToastActivity()
AG
fonte
muitos erros neste código .. mudanças como .Center para centro, whiteColor para branco, animateWithDuration para animar (duração, apenas muitos erros .. por favor, corrija isso ..
Siddharth
2

Para os que usam Xamarin.IOS, você pode fazer assim:

new UIAlertView(null, message, null, "OK", null).Show();

using UIKit; É necessário.

Daniele D.
fonte
2

Para mim, esta solução funciona bem: https://github.com/cruffenach/CRToast

insira a descrição da imagem aqui

Exemplo de como usar:

    NSDictionary *options = @{
                          kCRToastTextKey : @"Hello World!",
                          kCRToastTextAlignmentKey : @(NSTextAlignmentCenter),
                          kCRToastBackgroundColorKey : [UIColor redColor],
                          kCRToastAnimationInTypeKey : @(CRToastAnimationTypeGravity),
                          kCRToastAnimationOutTypeKey : @(CRToastAnimationTypeGravity),
                          kCRToastAnimationInDirectionKey : @(CRToastAnimationDirectionLeft),
                          kCRToastAnimationOutDirectionKey : @(CRToastAnimationDirectionRight)
                          };
[CRToastManager showNotificationWithOptions:options
                            completionBlock:^{
                                NSLog(@"Completed");
                            }];
Alex P
fonte
2

Sintaxe do Swift 4 para um atraso de 3 segundos:

present(alertController, animated: true, completion: nil)

DispatchQueue.main.asyncAfter(deadline: .now() + 3) {                 
    self.dismiss(animated: true, completion: nil)     
} 
Rikesan
fonte
Uau. Eu tive esse tipo de problema onde seu código me deu uma ideia do que fazer. Obrigado :)
Al Walid Ashik
1

Implementação rápida do Android Toast usando Alerta que se dissipa após 3 segundos.

    func showAlertView(title: String?, message: String?) {
    let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
    let okAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
    alertController.addAction(okAction)
    self.presentViewController(alertController, animated: true, completion: nil)


    let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(3 * Double(NSEC_PER_SEC)))
    dispatch_after(delayTime, dispatch_get_main_queue()) {
        print("Bye. Lovvy")
        alertController.dismissViewControllerAnimated(true, completion: nil)
    }
}

Para chamá-lo simplesmente:

self.showAlertView("Message sent...", message: nil)
ioopl
fonte
1

Para Swift 2.0 e considerando https://stackoverflow.com/a/5079536/6144027

                //TOAST
                let alertController = UIAlertController(title: "", message: "This is a Toast.LENGTH_SHORT", preferredStyle: .Alert)
                self!.presentViewController(alertController, animated: true, completion: nil)
                let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(2.0 * Double(NSEC_PER_SEC)))
                dispatch_after(delayTime, dispatch_get_main_queue()) {
                    alertController.dismissViewControllerAnimated(true, completion: nil)
                }
Marie Amida
fonte
1

Aqui está sua solução:
Coloque o código abaixo em seu projeto Xcode e divirta-se,

- (void)showMessage:(NSString*)message atPoint:(CGPoint)point {
const CGFloat fontSize = 16;

UILabel* label = [[UILabel alloc] initWithFrame:CGRectZero];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont fontWithName:@"Helvetica-Bold" size:fontSize];
label.text = message;
label.textColor = UIColorFromRGB(0x07575B);
[label sizeToFit];

label.center = point;

[self.view addSubview:label];

[UIView animateWithDuration:0.3 delay:1 options:0 animations:^{
    label.alpha = 0;
} completion:^(BOOL finished) {
    label.hidden = YES;
    [label removeFromSuperview];
}];
}

Como usar ?

[self showMessage:@"Toast in iOS" atPoint:CGPointMake(160, 695)];
Deepak Kumar
fonte
0

Novamente, se estiver usando IOS no Xamarin, há um novo componente chamado BTProgressHUD no armazenamento de componentes

bruce
fonte
0

1) Baixe toast-notifications-ios a partir deste link

2) vá para Targets -> Build Phases e adicione -fno-objc-arc ao "compilador Sources" para arquivos relevantes

3) fazer uma função e #import "iToast.h"

-(void)showToast :(NSString *)strMessage {
    iToast * objiTost = [iToast makeText:strMessage];
    [objiTost setFontSize:11];
    [objiTost setDuration:iToastDurationNormal];
    [objiTost setGravity:iToastGravityBottom];
    [objiTost show];
}

4) ligue para onde for necessário exibir a mensagem do sistema

[self showToast:@"This is example text."];
Hardik Thakkar
fonte
0

Pensei numa maneira simples de fazer o brinde! usando UIAlertController sem botão! Usamos o texto do botão como nossa mensagem! pegue? veja o código abaixo:

func alert(title: String?, message: String?, bdy:String) {
    let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
    let okAction = UIAlertAction(title: bdy, style: .Cancel, handler: nil)
    alertController.addAction(okAction)
        self.presentViewController(alertController, animated: true, completion: nil)


    let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(2 * Double(NSEC_PER_SEC)))
    dispatch_after(delayTime, dispatch_get_main_queue()) {
        //print("Bye. Lovvy")
        alertController.dismissViewControllerAnimated(true, completion: nil) 
    }    
}

use-o assim:

self.alert(nil,message:nil,bdy:"Simple Toast!") // toast
self.alert(nil,message:nil,bdy:"Alert") // alert with "Alert" button
Cal Johnston
fonte
0

Foi assim que fiz no Swift 3.0. Criei a extensão UIView e chamei self.view.showToast (mensagem: "Message Here", duração: 3.0) e self.view.hideToast ()

extension UIView{
var showToastTag :Int {return 999}

//Generic Show toast
func showToast(message : String, duration:TimeInterval) {

    let toastLabel = UILabel(frame: CGRect(x:0, y:0, width: (self.frame.size.width)-60, height:64))

    toastLabel.backgroundColor = UIColor.gray
    toastLabel.textColor = UIColor.black
    toastLabel.numberOfLines = 0
    toastLabel.layer.borderColor = UIColor.lightGray.cgColor
    toastLabel.layer.borderWidth = 1.0
    toastLabel.textAlignment = .center;
    toastLabel.font = UIFont(name: "HelveticaNeue", size: 17.0)
    toastLabel.text = message
    toastLabel.center = self.center
    toastLabel.isEnabled = true
    toastLabel.alpha = 0.99
    toastLabel.tag = showToastTag
    toastLabel.layer.cornerRadius = 10;
    toastLabel.clipsToBounds  =  true
    self.addSubview(toastLabel)

    UIView.animate(withDuration: duration, delay: 0.1, options: .curveEaseOut, animations: {
        toastLabel.alpha = 0.95
    }, completion: {(isCompleted) in
        toastLabel.removeFromSuperview()
    })
}

//Generic Hide toast
func hideToast(){
    if let view = self.viewWithTag(self.showToastTag){
        view.removeFromSuperview()
    }
  }
}
Gyanendra Singh
fonte