tutorial the programming objective language curso apple ios swift

ios - the - ¿Cómo brindar por el mensaje en Swift?



the swift programming language pdf (17)

¿Hay alguna manera de brindar mensajes de forma rápida?

Lo intenté en el objetivo c pero no pude encontrar una solución rápida.

[self.view makeToast:@"Account created Successfully" duration:0.5 position:@"bottom"];


Código @ mr-bean actualizado a la última versión de Swift (3.x)

let toastLabel = UILabel(frame: CGRect(x: self.view.frame.size.width/2 - 150, y: self.view.frame.size.height-100, width: 300, height: 35)) toastLabel.backgroundColor = UIColor.black toastLabel.textColor = UIColor.white toastLabel.textAlignment = NSTextAlignment.center self.view.addSubview(toastLabel) toastLabel.text = message toastLabel.alpha = 1.0 toastLabel.layer.cornerRadius = 10; toastLabel.clipsToBounds = true UIView.animate(withDuration: 4.0, animations: { toastLabel.alpha = 0.0 })


En lugar de usar UILabel usar UITextView obtiene mejores resultados.

func showToast(message: String) { let toastLabel = UITextView(frame: CGRect(x: self.view.frame.size.width/16, y: self.view.frame.size.height-150, width: self.view.frame.size.width * 7/8, height: 35)) toastLabel.backgroundColor = UIColor.black.withAlphaComponent(0.6) toastLabel.textColor = UIColor.white toastLabel.textAlignment = .center; toastLabel.text = " /(message) " toastLabel.alpha = 1.0 toastLabel.layer.cornerRadius = 10; toastLabel.clipsToBounds = true toastLabel.font = UIFont(name: (toastLabel.font?.fontName)!, size: 16) toastLabel.layoutEdgeInsets.left = 8 toastLabel.layoutEdgeInsets.right = 8 toastLabel.center.x = self.view.frame.size.width/2 self.view.addSubview(toastLabel) UIView.animate(withDuration: 5.0, delay: 0.1, options: .curveEaseOut, animations: { toastLabel.alpha = 0.0 }, completion: {(isCompleted) in toastLabel.removeFromSuperview() }) }

Se agrega espacio con el mensaje para proporcionar un buen espacio en ambos extremos para que se vea bien. Versión modificada de la respuesta de


Esto te ayudará a hacer el brindis en el centro con el relleno adecuado

func showToast(message:String,view:UIView){ let toastLabel = PaddingLabel() toastLabel.frame = CGRect(x:0, y: view.frame.size.height-100, width: view.frame.width-50, height: 0) toastLabel.backgroundColor = UIColor.black.withAlphaComponent(0.6) toastLabel.textColor = UIColor.white toastLabel.textAlignment = .center; toastLabel.font = UIFont(name: "Montserrat-Light", size: 12.0) toastLabel.text = message toastLabel.alpha = 1.0 toastLabel.layer.cornerRadius = 10; toastLabel.clipsToBounds = true toastLabel.sizeToFit() toastLabel.frame.origin.x=(view.frame.width/2)-(toastLabel.frame.width/2) view.addSubview(toastLabel) UIView.animate(withDuration: 4.0, delay: 0.1, options: .curveEaseOut, animations: { toastLabel.alpha = 0.0 }, completion: {(isCompleted) in toastLabel.removeFromSuperview() }) }

Y agregue este archivo PaddingLabel para el relleno de etiquetas

import Foundation import UIKit class PaddingLabel: UILabel { let padding=UIEdgeInsetsMake(5, 10, 5,10) override func drawText(in rect: CGRect) { super.drawText(in: UIEdgeInsetsInsetRect(rect, padding)) } override func sizeThatFits(_ size: CGSize) -> CGSize { let superSizeThatFits=super.sizeThatFits(size) let width=superSizeThatFits.width+padding.left+padding.right let height=superSizeThatFits.height+padding.top+padding.bottom return CGSize(width: width, height: height) } }


Hay una biblioteca de terceros que admite notificaciones de brindis personalizables con una sola línea de código. Aquí hay un ejemplo simple de esto:

import Toast_Swift ... // basic usage self.view.makeToast("This is a piece of toast") // toast with a specific duration and position self.view.makeToast("This is a piece of toast", duration: 3.0, position: .top)

https://github.com/scalessec/Toast-Swift

(Actualizado para Swift 3/4 +)


He estado usando esta extensión cuando alguna vez necesito un mensaje tostado como Android. Simplemente copie la extensión a su proyecto y luego en su clase UIViewController, llame a la función como

self.toastMessage("Downloading...") // Extention is below extension UIViewController { func toastMessage(_ message: String){ guard let window = UIApplication.shared.keyWindow else {return} let messageLbl = UILabel() messageLbl.text = message messageLbl.textAlignment = .center messageLbl.font = UIFont.systemFont(ofSize: 12) messageLbl.textColor = .white messageLbl.backgroundColor = UIColor(white: 0, alpha: 0.5) let textSize:CGSize = messageLbl.intrinsicContentSize let labelWidth = min(textSize.width, window.frame.width - 40) messageLbl.frame = CGRect(x: 20, y: window.frame.height - 90, width: labelWidth + 30, height: textSize.height + 20) messageLbl.center.x = window.center.x messageLbl.layer.cornerRadius = messageLbl.frame.height/2 messageLbl.layer.masksToBounds = true window.addSubview(messageLbl) DispatchQueue.main.asyncAfter(deadline: .now() + 1) { UIView.animate(withDuration: 1, animations: { messageLbl.alpha = 0 }) { (_) in messageLbl.removeFromSuperview() } } }}


Lo que necesita exactamente es https://github.com/Rannie/Toast-Swift/blob/master/SwiftToastDemo/Toast/HRToast%2BUIView.swift .

Descargue la clase HRToast + UIView.swift y arrastre y suelte para proyectar. Asegúrese de marcar ''copiar elementos si es necesario'' en el cuadro de diálogo.

//Usage: 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")


Para Swift 4

Mi versión de un Toast que usa restricciones de diseño, con la ventaja de que funciona para cualquier tamaño de texto, tal como está (según la respuesta de Tony Franzis):

Simplemente llame: Toast.show(message: "My message", myViewControllerName)

class Toast { static func show(message: String, controller: UIViewController) { let toastContainer = UIView(frame: CGRect()) toastContainer.backgroundColor = UIColor.black.withAlphaComponent(0.6) toastContainer.alpha = 0.0 toastContainer.layer.cornerRadius = 25; toastContainer.clipsToBounds = true let toastLabel = UILabel(frame: CGRect()) toastLabel.textColor = UIColor.white toastLabel.textAlignment = .center; toastLabel.font.withSize(12.0) toastLabel.text = message toastLabel.clipsToBounds = true toastLabel.numberOfLines = 0 toastContainer.addSubview(toastLabel) controller.view.addSubview(toastContainer) toastLabel.translatesAutoresizingMaskIntoConstraints = false toastContainer.translatesAutoresizingMaskIntoConstraints = false let a1 = NSLayoutConstraint(item: toastLabel, attribute: .leading, relatedBy: .equal, toItem: toastContainer, attribute: .leading, multiplier: 1, constant: 15) let a2 = NSLayoutConstraint(item: toastLabel, attribute: .trailing, relatedBy: .equal, toItem: toastContainer, attribute: .trailing, multiplier: 1, constant: -15) let a3 = NSLayoutConstraint(item: toastLabel, attribute: .bottom, relatedBy: .equal, toItem: toastContainer, attribute: .bottom, multiplier: 1, constant: -15) let a4 = NSLayoutConstraint(item: toastLabel, attribute: .top, relatedBy: .equal, toItem: toastContainer, attribute: .top, multiplier: 1, constant: 15) toastContainer.addConstraints([a1, a2, a3, a4]) let c1 = NSLayoutConstraint(item: toastContainer, attribute: .leading, relatedBy: .equal, toItem: controller.view, attribute: .leading, multiplier: 1, constant: 65) let c2 = NSLayoutConstraint(item: toastContainer, attribute: .trailing, relatedBy: .equal, toItem: controller.view, attribute: .trailing, multiplier: 1, constant: -65) let c3 = NSLayoutConstraint(item: toastContainer, attribute: .bottom, relatedBy: .equal, toItem: controller.view, attribute: .bottom, multiplier: 1, constant: -75) controller.view.addConstraints([c1, c2, c3]) UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveEaseIn, animations: { toastContainer.alpha = 1.0 }, completion: { _ in UIView.animate(withDuration: 0.5, delay: 1.5, options: .curveEaseOut, animations: { toastContainer.alpha = 0.0 }, completion: {_ in toastContainer.removeFromSuperview() }) }) } }


Permítanme agregar esto a esta cadena de respuestas: esta biblioteca hace lo que necesita DCToastView lo que le permite proporcionar mensajes brindis desde el lado superior o inferior de la pantalla:

Solo tendrá que agregar el pod

pod ''DCToastView''

Importarlo donde quieras usarlo.

import DCToastView

Y úsalo

ToastPresenter.shared.show(in: self.view, message: "This is a toast")

Puede pasar las siguientes propiedades al método show:

  • vista : la vista en la que se presentará el brindis
  • mensaje : el mensaje que mostrará la tostada
  • toastPlace : el lugar que puede ser .down o .up
  • backgroundColor : el color de fondo de la tostada; predeterminado a negro
  • textColor : el color del texto del mensaje; predeterminado a blanco
  • timeOut : la cantidad de segundos para que la tostada se descarte si no se proporciona, significa que la tostada estará pegajosa (permanecerá hasta que se toque); el valor predeterminado es nulo
  • redondez : Cuán redonda será la tostada: .none, .low, .mid, .high; el valor predeterminado es .mid

Sé que hay respuestas aceptadas, pero todas parecen tener un gran defecto: si muestra varias tostadas en un corto período de tiempo, se mostrarán una encima de la otra. Aquí está mi implementación que tiene en cuenta este problema:

class Toast: UILabel { private let BOTTOM_MARGIN: CGFloat = 16 private let SIDE_MARGIN: CGFloat = 16 private let HEIGHT: CGFloat = 35 private let SHOW_TIME_SECONDS = TimeInterval(3) private let BACKGROUND_COLOR = UIColor.darkGray.withAlphaComponent(0.7).cgColor private let TEXT_COLOR = UIColor.white private let ANIMATION_DURATION_SEC = 0.33 private static var queue: [ToastHolder] = [] private static var showing: Toast? init(_ text: String) { super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) self.text = text self.textColor = TEXT_COLOR textAlignment = .center self.layer.backgroundColor = BACKGROUND_COLOR self.layer.cornerRadius = 5 } public func show(_ parent: UIViewController) { frame = CGRect(x: SIDE_MARGIN, y: UIScreen.main.bounds.height - BOTTOM_MARGIN - HEIGHT, width: UIScreen.main.bounds.width - 2 * SIDE_MARGIN, height: HEIGHT) if Toast.showing == nil { Log.d("showing /(String(describing: text))") Toast.showing = self alpha = 0 parent.view.addSubview(self) UIView.animate(withDuration: ANIMATION_DURATION_SEC, animations: { self.alpha = 1 }, completion: { (completed) in Timer.scheduledTimer(timeInterval: self.SHOW_TIME_SECONDS, target: self, selector: #selector(self.onTimeout), userInfo: nil, repeats: false) }) } else { Toast.queue.append(ToastHolder(self, parent)) } } @objc func onTimeout() { UIView.animate(withDuration: ANIMATION_DURATION_SEC, animations: { self.alpha = 0 }, completion: { (completed) in Toast.showing = nil self.removeFromSuperview() if !Toast.queue.isEmpty { let holder = Toast.queue.removeFirst() holder.toast.show(holder.parent) } }) } required init?(coder aDecoder: NSCoder) { fatalError("this initializer is not supported") } private class ToastHolder { let toast: Toast let parent: UIViewController init(_ t: Toast, _ p: UIViewController) { toast = t parent = p } } }

Uso:

Toast("my message").show(self)

Espero que ayude a alguien.


Si la necesidad es un simple mensaje Toast sin una personalización elegante de la fuente, la alineación, el color del texto, etc., entonces lo siguiente estaría bien

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 presenta la alerta desde la parte inferior de la pantalla y el temporizador se encarga de la duración de la pantalla. Puede agregar esto como una extensión a UIViewController y luego llamarlo desde cualquier lugar.


Simplemente agregue el siguiente método. Esto mostrará el mensaje en diferentes colores con animación (mensaje que aparece de izquierda a derecha y desaparece).

Swift 3.0 -

class Toast { class private func showAlert(backgroundColor:UIColor, textColor:UIColor, message:String) { let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate let label = UILabel(frame: CGRect.zero) label.textAlignment = NSTextAlignment.center label.text = message label.font = UIFont(name: "", size: 15) label.adjustsFontSizeToFitWidth = true label.backgroundColor = backgroundColor //UIColor.whiteColor() label.textColor = textColor //TEXT COLOR label.sizeToFit() label.numberOfLines = 4 label.layer.shadowColor = UIColor.gray.cgColor label.layer.shadowOffset = CGSize(width: 4, height: 3) label.layer.shadowOpacity = 0.3 label.frame = CGRect(x: appDelegate.window!.frame.size.width, y: 64, width: appDelegate.window!.frame.size.width, height: 44) label.alpha = 1 appDelegate.window!.addSubview(label) var basketTopFrame: CGRect = label.frame; basketTopFrame.origin.x = 0; UIView.animate(withDuration :2.0, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.1, options: UIViewAnimationOptions.curveEaseOut, animations: { () -> Void in label.frame = basketTopFrame }, completion: { (value: Bool) in UIView.animate(withDuration:2.0, delay: 2.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.1, options: UIViewAnimationOptions.curveEaseIn, animations: { () -> Void in label.alpha = 0 }, completion: { (value: Bool) in label.removeFromSuperview() }) }) } class func showPositiveMessage(message:String) { showAlert(backgroundColor: UIColor.green, textColor: UIColor.white, message: message) } class func showNegativeMessage(message:String) { showAlert(backgroundColor: UIColor.red, textColor: UIColor.white, message: message) } }


Swift 4.2 Muy fácil y super manera

let toastLabel = UILabel() toastLabel.lineBreakMode = .byWordWrapping toastLabel.numberOfLines = 0 toastLabel.text = "Type your message you want to show in toast" toastLabel.sizeToFit() //MARK Resize the Label Frame toastLabel.frame = CGRect(x: toastLabel.frame.origin.x, y: toastLabel.frame.origin.y, width: toastLabel.frame.size.width + 40, height: toastLabel.frame.size.height + 40) self.view.addSubview(toastLabel)


Tengo dos soluciones más en Swift 5:

La mejor solución (en mi opinión)

Ventaja:

  1. Funciona correctamente al girar la pantalla.
  2. Las restricciones se utilizan para el posicionamiento.
  3. Funciona correctamente con SafeArea.

Desventajas

  1. Se requiere extender la clase UILabel para agregar sangrías. Uno podría prescindir de esto colocando el UILabel en el UIVIew .

Código:

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

Cómo utilizar:

class MyController: UIViewController { override func viewDidLoad() { super.viewDidLoad() showToast("Message") } }

Otra solucion

Ventaja:

  1. En esta versión, no uso un enlace a UIViewController

Desventajas

  1. Después de la rotación de la pantalla, la etiqueta no se mueve.
  2. No funciona correctamente con cadenas de varias líneas.

Código:

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

Cómo utilizar:

Helper.showToast("Message")


si makeToast:duration:position: se define en el objetivo-c y se puede llamar, entonces el código rápido será

self.view.makeToast("Acount created Successfully", duration: 0.5, position: "bottom")

Sin embargo, es posible que deba usar un encabezado de puente para obtener acceso a esos métodos en su código rápido.


Swift 4

func showToast(message : String) { let toastLabel = UILabel(frame: CGRect(x: self.view.frame.size.width/2 - 75, y: self.view.frame.size.height-100, width: 150, height: 35)) toastLabel.backgroundColor = UIColor.black.withAlphaComponent(0.6) toastLabel.textColor = UIColor.white toastLabel.textAlignment = .center; toastLabel.font = UIFont(name: "Montserrat-Light", size: 12.0) toastLabel.text = message toastLabel.alpha = 1.0 toastLabel.layer.cornerRadius = 10; toastLabel.clipsToBounds = true self.view.addSubview(toastLabel) UIView.animate(withDuration: 4.0, delay: 0.1, options: .curveEaseOut, animations: { toastLabel.alpha = 0.0 }, completion: {(isCompleted) in toastLabel.removeFromSuperview() }) }

Llama a la función como

self.showToast(message: "Data Save.")


extension UIViewController { func showToast(message : String, font: UIFont) { let toastLabel = UILabel(frame: CGRect(x: self.view.frame.size.width/2 - 75, y: self.view.frame.size.height-100, width: 150, height: 35)) toastLabel.backgroundColor = UIColor.black.withAlphaComponent(0.6) toastLabel.textColor = UIColor.white toastLabel.font = font toastLabel.textAlignment = .center; toastLabel.text = message toastLabel.alpha = 1.0 toastLabel.layer.cornerRadius = 10; toastLabel.clipsToBounds = true self.view.addSubview(toastLabel) UIView.animate(withDuration: 4.0, delay: 0.1, options: .curveEaseOut, animations: { toastLabel.alpha = 0.0 }, completion: {(isCompleted) in toastLabel.removeFromSuperview() }) } }


static func popUp(context ctx: UIViewController, msg: String) { let toast = UILabel(frame: CGRect(x: 16, y: ctx.view.frame.size.height / 2, width: ctx.view.frame.size.width - 32, height: 100)) toast.backgroundColor = UIColor.lightGray toast.textColor = UIColor.white toast.textAlignment = .center; toast.numberOfLines = 3 toast.font = UIFont.systemFont(ofSize: 20) toast.layer.cornerRadius = 12; toast.clipsToBounds = true toast.text = msg ctx.view.addSubview(toast) UIView.animate(withDuration: 5.0, delay: 0.2, options: .curveEaseOut, animations: { toast.alpha = 0.0 }, completion: {(isCompleted) in toast.removeFromSuperview() }) }

Entonces solo llámalo desde UIViewController

popUp(context: self, msg: "Your message")