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

IosToast

Ios Problem Overview


I have made Android application a few months ago. The Toast class is very useful for me. I do not need to consider the main Thread and place to show it. Anywhere I can show it and just leave that and it is automatically disappeared.

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

That's it. ^^

What about iPhone? Is there something like the Toast? Just show message and do not need to care about it. It will be automatically disappeared.

Ios Solutions


Solution 1 - Ios

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

Solution 2 - Ios

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

Solution 3 - Ios

Solution 4 - Ios

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")

Solution 5 - Ios

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

Solution 6 - Ios

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

}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmooongcleView Question on Stackoverflow
Solution 1 - IosSSemashkoView Answer on Stackoverflow
Solution 2 - IosQuentinView Answer on Stackoverflow
Solution 3 - IoskitimenpolkuView Answer on Stackoverflow
Solution 4 - IospetrsynView Answer on Stackoverflow
Solution 5 - IosMahesh GiriView Answer on Stackoverflow
Solution 6 - Ioswojciech_maciejewskiView Answer on Stackoverflow