What is the android.widget.Toast equivalent for iOS applications?

半世苍凉 提交于 2019-11-28 17:24:19

There is no class "out-of-the-box" in UIKit to do this. But it is quite easy to create a class that will offer this behavior.

You just have to create a class that inherit from UIView. This class will have the responsibility - to create what you want to display, - to add itself in parent view hierarchy - to dismiss itself using a timer.

You will be able to use it like :

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

Regards, Quentin

I've been writing for Android for a long time and I am missing Toast. I've implemented one. Need code? here you are:

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

Call from ViewController

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

Edit: Updated for Swift 3

Here is a Swift 3 version based on wojciech_maciejewski's answer. This looks more like Android Toast and doesn't stack toasts on each other. It draws toast into the center of the screen. It can handle long multiline texts.

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() })
    }
}

Usage from another controller:

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

I'm posting swift version of Scarmysun answer:) many thanks

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() })
    }

}

You can do this in many ways one of the way is using UIAlertViewController() in 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)

                                })
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!