Si no hay resultados en la vista de tabla, muestra "Sin resultados" en la pantalla


114

Tengo un tableview, donde a veces puede que no haya resultados para listar, así que me gustaría poner algo que diga "sin resultados" si no hay resultados (¿una etiqueta o una celda de vista de tabla?).

¿Existe una forma más sencilla de hacer esto?

Intentaría una labeldetrás y tableviewluego ocultaría una de las dos según los resultados, pero como estoy trabajando con una TableViewControllery no una normal, ViewControllerno estoy seguro de qué tan inteligente o factible es.

También estoy usando Parsey subclasificando como PFQueryTableViewController:

@interface TableViewController : PFQueryTableViewController

Puedo proporcionar cualquier información adicional necesaria, ¡solo hágamelo saber!

TableViewController Escena en Storyboard:

ingrese la descripción de la imagen aquí

EDITAR: Por Midhun MP, aquí está el código que estoy usando

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    NSInteger numOfSections = 0;
    if ([self.stringArray count] > 0)
    {
        self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
        numOfSections                 = 1;
        //yourTableView.backgroundView   = nil;
        self.tableView.backgroundView = nil;
    }
    else
    {
        UILabel *noDataLabel         = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, self.tableView.bounds.size.height)];
        noDataLabel.text             = @"No data available";
        noDataLabel.textColor        = [UIColor blackColor];
        noDataLabel.textAlignment    = NSTextAlignmentCenter;
        //yourTableView.backgroundView = noDataLabel;
        //yourTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        self.tableView.backgroundView = noDataLabel;
        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    }

    return numOfSections;
}

Y aquí está la Vista que obtengo, todavía tiene líneas de separación. Tengo la sensación de que se trata de un pequeño cambio, pero no estoy seguro de por qué aparecen las líneas de separación.

ingrese la descripción de la imagen aquí


Creo que el truco fue configurar footerView vacío en tableview para deshacerse de las líneas.
Ben Sinclair

@Andy ¿Qué quieres decir con eso?
SRMR

No use la solución agregada a esta pregunta. Los métodos de origen de datos de la vista de tabla nunca deben hacer más de lo que se supone que deben hacer. numberOfSectionsdebería devolver un recuento y eso es todo. Lo mismo para numberOfRowsInSection. Estos se pueden llamar muchas veces en cualquier momento. Nunca actualice las vistas ni actualice los datos ni haga nada excepto devolver un recuento. La lógica para actualizar las vistas nunca debe estar en estos métodos.
rmaddy

Respuestas:


206

Puede lograrlo fácilmente utilizando la backgroundViewpropiedad de UITableView.

C objetivo:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    NSInteger numOfSections = 0;
    if (youHaveData)
    {
        yourTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
        numOfSections                = 1;
        yourTableView.backgroundView = nil;
    }
    else
    {   
        UILabel *noDataLabel         = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, yourTableView.bounds.size.width, yourTableView.bounds.size.height)];
        noDataLabel.text             = @"No data available";
        noDataLabel.textColor        = [UIColor blackColor];
        noDataLabel.textAlignment    = NSTextAlignmentCenter;
        yourTableView.backgroundView = noDataLabel;
        yourTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    }

    return numOfSections;
}

Rápido:

func numberOfSections(in tableView: UITableView) -> Int
{
    var numOfSections: Int = 0
    if youHaveData
    {
        tableView.separatorStyle = .singleLine
        numOfSections            = 1
        tableView.backgroundView = nil
    }
    else
    {
        let noDataLabel: UILabel  = UILabel(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: tableView.bounds.size.height))
        noDataLabel.text          = "No data available"
        noDataLabel.textColor     = UIColor.black
        noDataLabel.textAlignment = .center
        tableView.backgroundView  = noDataLabel
        tableView.separatorStyle  = .none
    }
    return numOfSections
}

Referencia Referencia de la clase UITableView

backgroundView Propiedad

La vista de fondo de la vista de tabla.

Declaración

Rápido

var backgroundView: UIView?

C objetivo

@property(nonatomic, readwrite, retain) UIView *backgroundView

Discusión

La vista de fondo de una vista de tabla cambia automáticamente de tamaño para que coincida con el tamaño de la vista de tabla. Esta vista se coloca como una subvista de la vista de tabla detrás de todas las celdas, vistas de encabezado y vistas de pie de página.

Debe establecer esta propiedad en nil para establecer el color de fondo de la vista de tabla.


¡Gracias por la respuesta! ¿Significa esto que necesito una tableViewsalida para poder hacerlo yourTableView.backgroundView? Estoy usando un, TableViewControllerasí que no tengo una salida para él en este momento, por eso me pregunto.
SRMR

1
UITableViewControllerya tiene una propiedad nombrada, tableViewpor lo que no necesita crear una
Cihan Tek

self.tableView
Entendido

1
Corrección. Después de más pruebas, tuve que hacer que la línea que mencioné devolviera el mismo valor. numOfSections = 1. Si lo pongo en cero y mi vista de tabla está vacía, funciona, pero cuando creo una celda y luego la elimino, en lugar de eliminar y mostrar el mensaje, se bloquea con el siguiente error. *** Finalizando la aplicación debido a la excepción no detectada 'NSInternalInconsistencyException', motivo: 'Error interno de UITableView: no se puede generar un nuevo mapa de sección con el recuento de la sección anterior: 1 y el recuento de la nueva sección: 0'. No sé por qué funciona devolver el mismo valor, pero funciona y funciona como debería.
ChrisOSX

2
No use esta solución. Los métodos de origen de datos de la vista de tabla nunca deben hacer más de lo que se supone que deben hacer. numberOfSectionsdebería devolver un recuento y eso es todo. Lo mismo para numberOfRowsInSection. Estos se pueden llamar muchas veces en cualquier momento. Nunca actualice las vistas ni los datos, ni haga nada excepto devolver un recuento. La lógica para actualizar las vistas nunca debe estar en estos métodos.
rmaddy

107

Para Xcode 8.3.2 - Swift 3.1

Aquí hay una manera no tan conocida pero increíblemente fácil de lograr agregar una vista "Sin elementos" a una vista de tabla vacía que se remonta a Xcode 7. Dejaré que usted controle esa lógica que agrega / elimina el vista a la vista de fondo de la tabla, pero aquí está el flujo de un guión gráfico de Xcode (8.3.2):

  1. Seleccione la escena en el Storyboard que tiene su vista de tabla.
  2. Arrastre una UIView vacía al "Scene Dock" de esa escena

ingrese la descripción de la imagen aquí

  1. Agregue un UILabel y cualquier restricción a la nueva vista y luego cree un IBOutlet para esa vista

ingrese la descripción de la imagen aquí

  1. Asignar esa vista a tableView.backgroundView

ingrese la descripción de la imagen aquí

  1. ¡He aquí la magia!

ingrese la descripción de la imagen aquí

En última instancia, esto funciona siempre que desee agregar una vista simple a su controlador de vista que no necesariamente desea que se muestre de inmediato, pero que tampoco desea codificar a mano.


1
Esta técnica funciona para cualquier cosa para la que necesite una vista simple. También lo he usado para encabezados de sección de tabla personalizados. Realmente, puede usarlo para cualquier cosa para la que necesite una vista. Simplemente haga referencia a través de un IBOutlet y agréguelo como subvista en cualquier lugar donde necesite una vista personalizada.
Paul Bonneville

Como dijo @gmogames, después de usar IOS durante 2 años, esta es la primera vez que se sabe sobre el fondo de tableView. gracias hombre
Ali Adil

1
Gracias por esto. Solo para publicarlo, tuve que usar tableView.separatorStyle = .none y cambiar el tamaño de la UIView predeterminada para ver backgroundView. Estoy usando Xcode 9.4 con Swift 4.
Hammad Tariq

¿Cómo colocas la vista personalizada?
Nol4635

1
@ Nol4635 En el caso del fondo de la vista de tabla, simplemente asigne la vista que creó como IBOutlet al fondo de la vista de tabla o, si solo desea agregar la vista a cualquier otra vista, puede agregarla como una subvista. Tendrá que establecer los valores del marco, pero es como cualquier otra vista.
Paul Bonneville

30

Versión rápida del código anterior: -

func numberOfSectionsInTableView(tableView: UITableView) -> Int {

    var numOfSection: NSInteger = 0

    if CCompanyLogoImage.count > 0 {

        self.tableView.backgroundView = nil
        numOfSection = 1


    } else {

        var noDataLabel: UILabel = UILabel(frame: CGRectMake(0, 0, self.tableView.bounds.size.width, self.tableView.bounds.size.height))
        noDataLabel.text = "No Data Available"
        noDataLabel.textColor = UIColor(red: 22.0/255.0, green: 106.0/255.0, blue: 176.0/255.0, alpha: 1.0)
        noDataLabel.textAlignment = NSTextAlignment.Center
        self.tableView.backgroundView = noDataLabel

    }
    return numOfSection
}

Pero si está cargando información desde un JSON, debe verificar si el JSON está vacío o no, por lo tanto, si coloca un código como este, inicialmente muestra el mensaje "No hay datos" y luego desaparece. Porque después de que la tabla recarga los datos, el mensaje se oculta. Entonces, puede poner este código donde cargar datos JSON en una matriz. ENTONCES :-

func numberOfSectionsInTableView(tableView: UITableView) -> Int {

    return 1
}

func extract_json(data:NSData) {


    var error: NSError?

    let jsonData: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers , error: &error)
    if (error == nil) {
        if let jobs_list = jsonData as? NSArray
        {
            if jobs_list.count == 0 {

                var noDataLabel: UILabel = UILabel(frame: CGRectMake(0, 0, self.tableView.bounds.size.width, self.tableView.bounds.size.height))
                noDataLabel.text = "No Jobs Available"
                noDataLabel.textColor = UIColor(red: 22.0/255.0, green: 106.0/255.0, blue: 176.0/255.0, alpha: 1.0)
                noDataLabel.textAlignment = NSTextAlignment.Center
                self.tableView.backgroundView = noDataLabel

            }

            for (var i = 0; i < jobs_list.count ; i++ )
            {
                if let jobs_obj = jobs_list[i] as? NSDictionary
                {
                    if let vacancy_title = jobs_obj["VacancyTitle"] as? String
                    {
                        CJobTitle.append(vacancy_title)

                        if let vacancy_job_type = jobs_obj["VacancyJobType"] as? String
                        {
                            CJobType.append(vacancy_job_type)

                            if let company_name = jobs_obj["EmployerCompanyName"] as? String
                            {
                                CCompany.append(company_name)

                                    if let company_logo_url = jobs_obj["EmployerCompanyLogo"] as? String
                                    {
                                        //CCompanyLogo.append("http://google.com" + company_logo_url)

                                        let url = NSURL(string: "http://google.com" + company_logo_url )
                                        let data = NSData(contentsOfURL:url!)
                                        if data != nil {
                                            CCompanyLogoImage.append(UIImage(data: data!)!)
                                        }

                                        if let vacancy_id = jobs_obj["VacancyID"] as? String
                                        {
                                            CVacancyId.append(vacancy_id)

                                        }

                                    }

                            }

                        }
                    }
                }
            }
        }
    }
    do_table_refresh();


}

func do_table_refresh() {

    dispatch_async(dispatch_get_main_queue(), {
        self.tableView.reloadData()
        return
    })
}

Esto funciona muy bien para mostrar la etiqueta cuando no hay datos en las filas. Sin embargo, ¿cuál es la mejor manera de manejar cuando los datos entran y self.tableView.reloadData()se llaman? Descubrí que está agregando mis nuevas filas, pero noDataLabeltodavía se muestra debajo de ellas.
tylerSF

1
Si su matriz tiene un elemento, simplemente configure self.tableView.backgroundView = nil
Chathuranga Silva

if jobs_list.count == 0 {// agregar el código anterior dado} else {self.tableView.backgroundView = nil}
Chathuranga Silva

Perfecto. agregar self.tableView.backgroundView = nilmi declaración if antes return jobs_list.count funciona bien. gracias
tylerSF

No use la primera solución en esta respuesta. Los métodos de origen de datos de la vista de tabla nunca deben hacer más de lo que se supone que deben hacer. numberOfSectionsdebería devolver un recuento y eso es todo. Lo mismo para numberOfRowsInSection. Estos se pueden llamar muchas veces en cualquier momento. Nunca actualice las vistas ni los datos, ni haga nada excepto devolver un recuento. La lógica para actualizar las vistas nunca debe estar en estos métodos.
rmaddy

6

Puedes probar este control. Está bastante bien. DZNEmptyDataSet

O si yo fuera tu todo lo que haría es

  • Verifique si su matriz de datos está vacía
  • Si está vacío, agregue un objeto llamado @ "Sin datos"
  • Mostrar esa cadena en cell.textLabel.text

Pan comido


5

Swift 3 (actualizado):

override func numberOfSections(in tableView: UITableView) -> Int {
    if myArray.count > 0 {
        self.tableView.backgroundView = nil
        self.tableView.separatorStyle = .singleLine
        return 1
    }

    let rect = CGRect(x: 0,
                      y: 0,
                      width: self.tableView.bounds.size.width,
                      height: self.tableView.bounds.size.height)
    let noDataLabel: UILabel = UILabel(frame: rect)

    noDataLabel.text = "Custom message."
    noDataLabel.textColor = UIColor.white
    noDataLabel.textAlignment = NSTextAlignment.center
    self.tableView.backgroundView = noDataLabel
    self.tableView.separatorStyle = .none

    return 0
}

No use esta solución. Los métodos de origen de datos de la vista de tabla nunca deben hacer más de lo que se supone que deben hacer. numberOfSectionsdebería devolver un recuento y eso es todo. Lo mismo para numberOfRowsInSection. Estos se pueden llamar muchas veces en cualquier momento. Nunca actualice las vistas ni los datos, ni haga nada excepto devolver un recuento. La lógica para actualizar las vistas nunca debe estar en estos métodos.
rmaddy

Estoy de acuerdo. Esta solución se puede mejorar, pero también se puede utilizar.
Teodor Ciuraru

¿Cómo puede estar de acuerdo en que no debe usar esta solución y luego afirmar que también se puede usar? Eso es una contradicción.
maddy

Estoy de acuerdo en que esta solución se puede mejorar, pero, en su estado actual, también funcionará.
Teodor Ciuraru

5

Swift3.0

Espero que sirva a su propósito ... En su UITableViewController.

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if searchController.isActive && searchController.searchBar.text != "" {
        if filteredContacts.count > 0 {
            self.tableView.backgroundView = .none;
            return filteredContacts.count
        } else {
            Helper.EmptyMessage(message: ConstantMap.NO_CONTACT_FOUND, viewController: self)
            return 0
        }
    } else {
        if contacts.count > 0 {
            self.tableView.backgroundView = .none;
            return contacts.count
        } else {
            Helper.EmptyMessage(message: ConstantMap.NO_CONTACT_FOUND, viewController: self)
            return 0
        }
    }
}

Clase auxiliar con función:

 /* Description: This function generate alert dialog for empty message by passing message and
           associated viewcontroller for that function
           - Parameters:
            - message: message that require for  empty alert message
            - viewController: selected viewcontroller at that time
         */
        static func EmptyMessage(message:String, viewController:UITableViewController) {
            let messageLabel = UILabel(frame: CGRect(x: 0, y: 0, width: viewController.view.bounds.size.width, height: viewController.view.bounds.size.height))
            messageLabel.text = message
            let bubbleColor = UIColor(red: CGFloat(57)/255, green: CGFloat(81)/255, blue: CGFloat(104)/255, alpha :1)

            messageLabel.textColor = bubbleColor
            messageLabel.numberOfLines = 0;
            messageLabel.textAlignment = .center;
            messageLabel.font = UIFont(name: "TrebuchetMS", size: 18)
            messageLabel.sizeToFit()

            viewController.tableView.backgroundView = messageLabel;
            viewController.tableView.separatorStyle = .none;
        }

No use esta solución. Los métodos de origen de datos de la vista de tabla nunca deben hacer más de lo que se supone que deben hacer. numberOfSectionsdebería devolver un recuento y eso es todo. Lo mismo para numberOfRowsInSection. Estos se pueden llamar muchas veces en cualquier momento. Nunca actualice las vistas ni los datos, ni haga nada excepto devolver un recuento. La lógica para actualizar las vistas nunca debe estar en estos métodos.
rmaddy

3

Creo que la forma más elegante de resolver su problema es cambiar de a UITableViewControllera a UIViewControllerque contiene a UITableView. De esta manera, puede agregar lo UIViewque desee como subvistas de la vista principal.

No recomendaría usar un UITableViewCell para hacer esto, es posible que necesite agregar cosas adicionales en el futuro y las cosas pueden ponerse feas rápidamente.

También puede hacer algo como esto, pero tampoco es la mejor solución.

UIWindow* window = [[UIApplication sharedApplication] keyWindow];
[window addSubview: OverlayView];

Gracias por el color alrededor del cual es la forma más elegante de implementar, siempre una buena forma de pensarlo. Podría intentar cambiar mi guión gráfico para usar un archivo que UIViewControllercontenga un UITableView.
SRMR

1
Esa es la forma más preparada para el futuro. Nunca he usado un UITableViewControlleryo mismo, porque usarlo no es mucho más fácil que hacerlo al revés, pero limita tu capacidad para cambiar las cosas en el futuro.
Cihan Tek

Esto no es a prueba de futuro si tiene barras translúcidas. Recomiendo encarecidamente que no. Como mínimo, cree un UIViewController que contenga un UITableViewController y ajuste las cosas de forma adecuada.
xtravar

3

Utilice este código en su numberOfSectionsInTableViewmétodo: -

if ([array count]==0
{

    UILabel *fromLabel = [[UILabel alloc]initWithFrame:CGRectMake(50, self.view.frame.size.height/2, 300, 60)];                                                                                        
    fromLabel.text =@"No Result";
    fromLabel.baselineAdjustment = UIBaselineAdjustmentAlignBaselines;
    fromLabel.backgroundColor = [UIColor clearColor];
    fromLabel.textColor = [UIColor lightGrayColor];
    fromLabel.textAlignment = NSTextAlignmentLeft;
    [fromLabel setFont:[UIFont fontWithName:Embrima size:30.0f]];
    [self.view addSubview:fromLabel];
    [self.tblView setHidden:YES];
}

1
No use esta solución. Los métodos de origen de datos de la vista de tabla nunca deben hacer más de lo que se supone que deben hacer. numberOfSectionsdebería devolver un recuento y eso es todo. Lo mismo para numberOfRowsInSection. Estos se pueden llamar muchas veces en cualquier momento. Nunca actualice las vistas ni los datos, ni haga nada excepto devolver un recuento. La lógica para actualizar las vistas nunca debe estar en estos métodos.
rmaddy

2

SWIFT 3

        let noDataLabel: UILabel     = UILabel(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: tableView.bounds.size.height))
        noDataLabel.text             = "No data available"
        noDataLabel.textColor        = UIColor.white
        noDataLabel.font             = UIFont(name: "Open Sans", size: 15)
        noDataLabel.textAlignment    = .center
        tableView.backgroundView = noDataLabel
        tableView.separatorStyle = .none

2

Si no usa el pie de página de la vista de tabla y no desea que la vista de tabla llene la pantalla con celdas de tabla predeterminadas vacías, le sugiero que configure el pie de página de la vista de tabla en una UIView vacía. No conozco la sintaxis correcta para hacer esto en obj-c o Swift, pero en Xamarin.iOS lo haría así:

public class ViewController : UIViewController
{
    UITableView _table;

    public ViewController (IntPtr handle) : base (handle)
    {
    }

    public override void ViewWillAppear(bool animated) {
        // Initialize table

        _table.TableFooterView = new UIView();
    }
}

El código anterior dará como resultado una vista de tabla sin las celdas vacías


2

Aquí está la solución que funcionó para mí.

  1. Agregue el siguiente código a un archivo nuevo.

  2. Cambie su clase de tabla a la clase personalizada "MyTableView" desde el guión gráfico o .xib

(esto funcionará solo para la primera sección. Si desea personalizar más, haga cambios en la función reloadData () de MyTableView en consecuencia para otras secciones)

public class MyTableView: UITableView {

    override public func reloadData() {
        super.reloadData()

        if self.numberOfRows(inSection: 0) == 0 {
            if self.viewWithTag(1111) == nil {
                let noDataLabel = UILabel()
                noDataLabel.textAlignment = .center
                noDataLabel.text = "No Data Available"
                noDataLabel.tag = 1111
                noDataLabel.center = self.center
                self.backgroundView = noDataLabel
            }

        } else {
            if self.viewWithTag(1111) != nil {
                self.backgroundView = nil
            }
        }
    }
}

Este es un buen enfoque. Agregué algunas mejoras a continuación para hacerlo más completo. 1. Almacene en caché el estilo de separador de la vista de tabla y restáurelo en la transición de estado vacío / no vacío para que esta subclase sea aplicable a los casos de uso en los que se desean diferentes estilos de separador. 2. Agregue @IBInspectable var emptyStateText: String?y marque esta clase, ya que @IBDesignableentonces podrá cambiar diferentes textos de estado vacío para diferentes escenas en el guión gráfico o xibs. ¡Disfrutar! :)
Egist Li

1

Presentaría una vista superpuesta que tiene el aspecto y el mensaje que desea si la vista de tabla no tiene resultados. Puede hacerlo en ViewDidAppear, para tener los resultados antes de mostrar / no mostrar la vista.


1

Si quieres hacer esto sin ningún código, ¡prueba esto!

Haga clic en su tableView.

tableView captura de pantalla

Cambie el estilo de "simple" a "agrupado".

Propiedades de vista de tabla captura de pantalla-2

Ahora, cuando uses ...

tableView.backgroundView = INSERTAR SU ETIQUETA O VER

¡No mostrará los separadores!


1

Agregue este código en un archivo y cambie su tipo de colección a CustomCollectionView

import Foundation

class CustomCollectionView: UICollectionView {

  var emptyModel = EmptyMessageModel()
  var emptyView: EmptyMessageView?
  var showEmptyView: Bool = true

  override func reloadData() {
    super.reloadData()

    emptyView?.removeFromSuperview()
    self.backgroundView = nil

    if !showEmptyView {
      return
    }

    if numberOfSections < 1 {
      let rect = CGRect(x: 0,
                        y: 0,
                        width: self.bounds.size.width,
                        height: self.bounds.size.height)

      emptyView = EmptyMessageView()
      emptyView?.frame = rect
      if let emptyView = emptyView {
        //                self.addSubview(emptyView)
        self.backgroundView = emptyView
      }
      emptyView?.setView(with: emptyModel)

    } else {
      emptyView?.removeFromSuperview()
      self.backgroundView = nil
    }
  }
}

class EmptyMessageView: UIView {

  @IBOutlet weak var messageLabel: UILabel!
  @IBOutlet weak var imageView: UIImageView!

  var view: UIView!

  override init(frame: CGRect) {
    super.init(frame: frame)
    xibSetup()
  }

  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    xibSetup()
  }

  func xibSetup() {
    view = loadViewFromNib()

    view.frame = bounds

    view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    addSubview(view)
  }

  func loadViewFromNib() -> UIView {

    let bundle = Bundle(for: type(of: self))
    let nib = UINib(nibName: "EmptyMessageView", bundle: bundle)
    let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView

    return view
  }

  func setView(with model: EmptyMessageModel) {
    messageLabel.text = model.message ?? ""
    imageView.image = model.image ?? #imageLiteral(resourceName: "no_notification")
  }
}

///////////
class EmptyMessageModel {
  var message: String?
  var image: UIImage?

  init(message: String = "No data available", image: UIImage = #imageLiteral(resourceName: "no_notification")) {
    self.message = message
    self.image = image
  }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.