How to Toast message in Swift?

后端 未结 22 1013
暖寄归人
暖寄归人 2020-12-22 19:18

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         


        
相关标签:
22条回答
  • 2020-12-22 19:55

    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.

    0 讨论(0)
  • 2020-12-22 19:56

    I have two more solutions on Swift 5:

    Best solution (in my opinion)

    Advantage:

    1. Works correctly when rotating the screen.
    2. Constraints are used for positioning.
    3. Works correctly with SafeArea.

    Disadvantages:

    1. It is required to extend the 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:

    1. In this version, I don't use a binding to UIViewController

    Disadvantages:

    1. After screen rotation, the label does not move.
    2. Does not work correctly with multi-line strings.

    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")
    
    0 讨论(0)
  • 2020-12-22 19:56

    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)
    
    0 讨论(0)
  • 2020-12-22 19:59

    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()
                }
            }
        }
    
    0 讨论(0)
提交回复
热议问题