web-dev-qa-db-fra.com

Si aucun résultat d'affichage de tableau, affiche "Aucun résultat" à l'écran

J'ai un tableview, où parfois il peut ne pas y avoir de résultats à lister, alors je aimerais mettre quelque chose qui dit "pas de résultats" s'il n'y a pas de résultats (soit une étiquette ou une cellule de vue de table?).

Y a-t-il un moyen plus simple de faire cela?

Je voudrais essayer un label derrière le tableview puis cacher l'un des deux en fonction des résultats, mais comme je travaille avec un TableViewController et pas normal ViewController Je ne sais pas si c'est intelligent ou faisable.

J'utilise aussi Parse et les sous-classes en tant que PFQueryTableViewController:

@interface TableViewController : PFQueryTableViewController

Je peux fournir tous les détails supplémentaires nécessaires, faites le moi savoir!

TableViewController Scène dans le scénarimage:

enter image description here

EDIT: Par Midhun MP, voici le code que j'utilise

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

Et voici la vue que je reçois, il a toujours des lignes de séparation. J'ai l'impression que c'est un petit changement, mais je ne suis pas sûr de savoir pourquoi les lignes de séparation apparaissent?

enter image description here

105
SRMR

Vous pouvez facilement y parvenir en utilisant la propriété backgroundView de UITableView.

Objectif C:

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

Rapide:

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
}

Reference Référence de la classe UITableView

backgroundView Propriété

La vue d’arrière-plan de la vue tableau.

Déclaration

Rapide

var backgroundView: UIView?

Objective-C

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

Discussion

L’arrière-plan d’une vue de tableau est automatiquement redimensionné pour correspondre à la taille de la vue. Cette vue est placée en tant que sous-vue de la vue tableau derrière toutes les cellules, les vues d'en-tête et les vues de pied de page.

Vous devez définir cette propriété sur nil pour définir la couleur d'arrière-plan de la vue tableau.

196
Midhun MP

Pour Xcode 8.3.2 - Swift 3.1

Voici un moyen peu connu mais incroyablement facile d’ajouter une vue "Aucun élément" à une vue de table vide renvoyant à Xcode 7. Je vous laisse le soin de contrôler cette logique qui ajoute/supprime le affiche la vue d’arrière-plan de la table, mais voici le déroulement du storyboard Xcode (8.3.2):

  1. Sélectionnez la scène dans le Storyboard qui a votre vue de table.
  2. Faites glisser un UIView vide vers le "Dock de scènes" de cette scène

enter image description here

  1. Ajoutez un UILabel et toutes les contraintes à la nouvelle vue, puis créez un IBOutlet pour cette vue.

enter image description here

  1. Affecter cette vue à la tableView.backgroundView

enter image description here

  1. Voici la magie!

enter image description here

En fin de compte, cela fonctionne chaque fois que vous souhaitez ajouter à votre contrôleur de vue une vue simple que vous ne voulez pas nécessairement afficher immédiatement, mais que vous ne souhaitez pas non plus manipuler de code.

94
Paul Bonneville

Swift Version du code ci-dessus: -

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
}

Mais si vous chargez des informations à partir d'un JSON, vous devez vérifier si le JSON est vide ou non. Par conséquent, si vous mettez un code comme celui-ci, il affiche initialement le message "Aucune donnée" puis disparaît. Parce qu'après la table recharger des données le message cacher. Donc, vous pouvez mettre ce code où charger des données JSON dans un tableau. SO: -

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
    })
}
30
Chathuranga Silva

Vous pouvez essayer ce contrôle. C'est assez chouette. DZNEmptyDataSet

Ou si j'étais vous tout ce que je ferais est

  • Vérifiez si votre tableau de données est vide
  • S'il est vide, ajoutez-y un objet appelé @ "No Data"
  • Afficher cette chaîne dans cell.textLabel.text

Peasy facile

7
Sam B

Swift 3 (mise à jour):

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
}
5
Teodor Ciuraru

Swift3.

J'espère que cela servira votre but ...... Dans votre 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
        }
    }
}

Classe d'assistance avec fonction:

 /* 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;
        }
5
Ravindra Shekhawat

Je pense que le moyen le plus élégant de résoudre votre problème consiste à passer d'un UITableViewController à un UIViewController contenant un UITableView. De cette façon, vous pouvez ajouter ce que vous voulez UIView comme sous-vues de la vue principale.

Je ne recommanderais pas d'utiliser un UITableViewCell pour faire cela, vous pourriez avoir besoin d'ajouter d'autres choses dans le futur et les choses peuvent vite devenir laides.

Vous pouvez également faire quelque chose comme ça, mais ce n'est pas la meilleure solution non plus.

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

Utilisez ce code dans votre méthode numberOfSectionsInTableView: -

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];
}
3
Chandan

Voici la solution qui a fonctionné pour moi.

  1. Ajoutez le code suivant à un nouveau fichier.

  2. Changez votre classe de table en classe personnalisée "MyTableView" à partir de storyboard ou .xib

(Cela fonctionnera uniquement pour la première section. Si vous souhaitez personnaliser davantage, modifiez la fonction MyTableView reloadData () en conséquence pour les autres sections)

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
            }
        }
    }
}
2
ShrikantWalekar

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
Ahmed Safadi

Si vous voulez faire cela sans code, essayez ceci!

Cliquez sur votre tableView.

tableView Screenshot

Changez le style de "plain" à "grouped".

Table View properties screenshot-2

Maintenant, quand vous utilisez ....

tableView.backgroundView = INSERER VOTRE ETIQUETTE OR VIEW

Il ne montrera pas les séparateurs!

1
F. Morales

Si vous n'utilisez pas le pied de page tableview et que vous ne voulez pas que tableview remplisse l'écran avec des cellules de tableau par défaut vides, je vous suggère de définir votre pied de page tableview sur un UIView vide. Je ne connais pas la syntaxe correcte pour le faire dans obj-c ou Swift, mais dans Xamarin.iOS, je le ferais comme ceci:

public class ViewController : UIViewController
{
    UITableView _table;

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

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

        _table.TableFooterView = new UIView();
    }
}

Le code ci-dessus donnera lieu à une table sans les cellules vides

1
frmi

Je voudrais présenter une vue de superposition qui a l'apparence et le message que vous voulez si la vue de table n'a aucun résultat. Vous pouvez le faire dans ViewDidAppear, de sorte que vous ayez les résultats avant d'afficher/de ne pas afficher la vue.

1
Siriss

Ajoutez ce code dans un fichier et changez votre type de collection en 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
  }
}
1
ShrikantWalekar