Is there any way to Toast message in swift ?
I have tried in objective c but could not find solution in swift.
[self.view makeToast:@\"Account create
If the need is for a simple Toast message without fancy customization of font, alignment, text color, etc. then the following would do just fine
let messageVC = UIAlertController(title: "Message Title", message: "Account Created successfully" , preferredStyle: .actionSheet)
present(messageVC, animated: true) {
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false, block: { (_) in
messageVC.dismiss(animated: true, completion: nil)})}
.actionSheet
presents the alert from Bottom of the screen and the Timer takes care of the display duration. You can add this as an extension to UIViewController and then call it from anywhere.
I have two more solutions on Swift 5:
Best solution (in my opinion)
Advantage:
Disadvantages:
UILabel
class to add indents. One could do without this by placing the UILabel
in the UIVIew
.Code:
class ToastLabel: UILabel {
var textInsets = UIEdgeInsets.zero {
didSet { invalidateIntrinsicContentSize() }
}
override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
let insetRect = bounds.inset(by: textInsets)
let textRect = super.textRect(forBounds: insetRect, limitedToNumberOfLines: numberOfLines)
let invertedInsets = UIEdgeInsets(top: -textInsets.top, left: -textInsets.left, bottom: -textInsets.bottom, right: -textInsets.right)
return textRect.inset(by: invertedInsets)
}
override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: textInsets))
}
}
extension UIViewController {
static let DELAY_SHORT = 1.5
static let DELAY_LONG = 3.0
func showToast(_ text: String, delay: TimeInterval = DELAY_LONG) {
let label = ToastLabel()
label.backgroundColor = UIColor(white: 0, alpha: 0.5)
label.textColor = .white
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 15)
label.alpha = 0
label.text = text
label.clipsToBounds = true
label.layer.cornerRadius = 20
label.numberOfLines = 0
label.textInsets = UIEdgeInsets(top: 10, left: 15, bottom: 10, right: 15)
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
let saveArea = view.safeAreaLayoutGuide
label.centerXAnchor.constraint(equalTo: saveArea.centerXAnchor, constant: 0).isActive = true
label.leadingAnchor.constraint(greaterThanOrEqualTo: saveArea.leadingAnchor, constant: 15).isActive = true
label.trailingAnchor.constraint(lessThanOrEqualTo: saveArea.trailingAnchor, constant: -15).isActive = true
label.bottomAnchor.constraint(equalTo: saveArea.bottomAnchor, constant: -30).isActive = true
UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseIn, animations: {
label.alpha = 1
}, completion: { _ in
UIView.animate(withDuration: 0.5, delay: delay, options: .curveEaseOut, animations: {
label.alpha = 0
}, completion: {_ in
label.removeFromSuperview()
})
})
}
}
How to use:
class MyController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
showToast("Message")
}
}
Other solution
Advantage:
UIViewController
Disadvantages:
Code:
class Helper {
static let DELAY_SHORT = 1.5
static let DELAY_LONG = 3.0
static func showToast(_ text: String, delay: TimeInterval = DELAY_LONG) {
guard let window = UIApplication.shared.keyWindow else {
return
}
let label = BaseLabel()
label.backgroundColor = UIColor(white: 0, alpha: 0.5)
label.textColor = .white
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 15)
label.alpha = 0
label.text = text
label.numberOfLines = 0
var vertical: CGFloat = 0
var size = label.intrinsicContentSize
var width = min(size.width, window.frame.width - 60)
if width != size.width {
vertical = 10
label.textAlignment = .justified
}
label.textInsets = UIEdgeInsets(top: vertical, left: 15, bottom: vertical, right: 15)
size = label.intrinsicContentSize
width = min(size.width, window.frame.width - 60)
label.frame = CGRect(x: 20, y: window.frame.height - 90, width: width, height: size.height + 20)
label.center.x = window.center.x
label.layer.cornerRadius = min(label.frame.height/2, 25)
label.layer.masksToBounds = true
window.addSubview(label)
UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseIn, animations: {
label.alpha = 1
}, completion: { _ in
UIView.animate(withDuration: 0.5, delay: delay, options: .curveEaseOut, animations: {
label.alpha = 0
}, completion: {_ in
label.removeFromSuperview()
})
})
}
}
How to use:
Helper.showToast("Message")
Swift 5,If you want to use simple toast,Please find code below.
extension UIViewController{
func showToast(message : String, seconds: Double){
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
alert.view.backgroundColor = .black
alert.view.alpha = 0.5
alert.view.layer.cornerRadius = 15
self.present(alert, animated: true)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + seconds) {
alert.dismiss(animated: true)
}
}
}
Call It from UIViewController
self.showToast(message: "Updating...", seconds: 1.0)
You can create your own style of toast and align it to the center of the whole screen like this:
func showToast(message: String, in viewController: UIViewController) {
let toastContainer: UIView = {
let view = UIView(frame: CGRect())
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = UIColor.gray
view.alpha = 0.0
view.layer.cornerRadius = 12
view.clipsToBounds = true
return view
}()
let toastLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = message
label.textColor = UIColor.white
label.textAlignment = .center
label.font = label.font.withSize(20)
label.clipsToBounds = true
label.numberOfLines = 0
return label
}()
toastContainer.addSubview(toastLabel)
viewController.view.addSubview(toastContainer)
toastContainer.layer.zPosition = 1
NSLayoutConstraint.activate([
toastContainer.widthAnchor.constraint(equalToConstant: viewController.view.frame.width * 0.6),
toastContainer.heightAnchor.constraint(equalToConstant: viewController.view.frame.height * 0.1),
toastContainer.centerXAnchor.constraint(equalTo: viewController.view.centerXAnchor),
toastContainer.bottomAnchor.constraint(equalTo: viewController.view.bottomAnchor, constant:
-UIScreen.main.bounds.maxY / 2 + viewController.view.frame.height * 0.1 / 2
),
toastLabel.centerXAnchor.constraint(equalTo: toastContainer.centerXAnchor),
toastLabel.centerYAnchor.constraint(equalTo: toastContainer.centerYAnchor)
])
UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveEaseIn, animations: {
toastContainer.alpha = 1.0
}) { (_) in
UIView.animate(withDuration: 0.5, delay: 2, options: .curveEaseOut, animations: {
toastContainer.alpha = 0.0
}) { (_) in
toastContainer.removeFromSuperview()
}
}
}