J'ai un UITableView qui dans certains cas, il est légal d'être vide. Donc, au lieu d'afficher l'image d'arrière-plan de l'application, je préférerais imprimer un message convivial à l'écran, tel que:
Cette liste est maintenant vide
Quelle est la manière la plus simple de le faire?
iphone
ios
uitableview
uiview
cateof
la source
la source
Réponses:
La propriété backgroundView de UITableView est votre ami.
Dans
viewDidLoad
ou n'importe où, vousreloadData
devez déterminer si votre table est vide ou non et mettre à jour la propriété backgroundView de l'UITableView avec un UIView contenant un UILabel ou simplement le définir sur nil. C'est tout.Il est bien sûr possible de faire en sorte que la source de données d'UITableView fasse une double tâche et retourne une cellule spéciale "la liste est vide", cela me semble être un kludge. Il faut soudainement
numberOfRowsInSection:(NSInteger)section
calculer le nombre de lignes des autres sections sur lesquelles il n'a pas été demandé pour s'assurer qu'elles sont également vides. Vous devez également créer une cellule spéciale contenant le message vide. N'oubliez pas non plus que vous devez probablement changer la hauteur de votre cellule pour accueillir le message vide. Tout cela est faisable, mais cela semble être un pansement en plus du pansement.la source
backgroundView
propriété cachée est la voie à suivre. AvecDZNEmptyDataSet
, nous devons utiliser sonemptyDataSetSource
tableView.backgroundView!.userInteraction = true
après la ligne que vous définisseztableView.backgroundView = constructMyViewWithButtons()
ou comme vous le définissez.Identique à la réponse de Jhonston, mais je l'ai préférée comme extension:
Usage:
la source
func numberOfSections(in tableView: UITableView) -> Int
méthodeSur la base des réponses ici, voici un cours rapide que j'ai créé que vous pouvez utiliser dans votre
UITableViewController
.Dans votre,
UITableViewController
vous pouvez appeler celanumberOfSectionsInTableView(tableView: UITableView) -> Int
Avec un peu d'aide de http://www.appcoda.com/pull-to-refresh-uitableview-empty/
la source
viewController.tableView.separatorStyle = .none
n'est pas nécessaire.Je recommande la bibliothèque suivante: DZNEmptyDataSet
Le moyen le plus simple de l'ajouter dans votre projet est de l'utiliser avec des Cocaopods comme ceci:
pod 'DZNEmptyDataSet'
Dans votre TableViewController, ajoutez l'instruction d'importation suivante (Swift):
Ensuite, assurez-vous que votre classe est conforme à
DNZEmptyDataSetSource
etDZNEmptyDataSetDelegate
ainsi de suite:Dans votre
viewDidLoad
ajoutez les lignes de code suivantes:Maintenant, tout ce que vous avez à faire pour afficher l'état de vide est:
Ces méthodes ne sont pas obligatoires, il est également possible d'afficher simplement l'état vide sans bouton, etc.
Pour Swift 4
la source
Une façon de le faire serait de modifier votre source de données pour qu'elle renvoie
1
lorsque le nombre de lignes est égal à zéro et de produire une cellule spéciale (peut-être avec un identificateur de cellule différent) dans latableView:cellForRowAtIndexPath:
méthode.Cela peut devenir quelque peu compliqué si vous avez plusieurs contrôleurs de vue de table que vous devez maintenir, car quelqu'un finira par oublier d'insérer un contrôle zéro. Une meilleure approche consiste à créer une implémentation distincte d'une
UITableViewDataSource
implémentation qui renvoie toujours une seule ligne avec un message configurable (appelons-laEmptyTableViewDataSource
). Lorsque les données gérées par votre contrôleur de vue table changent, le code qui gère la modification vérifie si les données sont vides. S'il n'est pas vide, définissez votre contrôleur de vue de table avec sa source de données régulière; sinon, définissez-le avec une instance deEmptyTableViewDataSource
qui a été configurée avec le message approprié.la source
deleteRowsAtIndexPaths:withRowAnimation:
car le nombre renvoyé parnumberOfRowsInSection
doit correspondre au résultat de $ numRows - $ rowsDeleted.J'utilise le message titleForFooterInSection pour cela. Je ne sais pas si c'est sous-optimal ou non, mais ça marche.
la source
return tableView.numberOfRowsInSection(section) == 0 ? "This list is now empty" : nil
Donc pour une solution plus sûre:
et pour
UICollectionView
aussi:Solution plus générique:
la source
Je ne peux que recommander de faire glisser et déposer un UITextView dans le TableView après les cellules. Connectez-vous au ViewController et masquez-le / affichez-le le cas échéant (par exemple chaque fois que la table se recharge).
la source
Utiliser le backgroundView est très bien, mais il ne défile pas bien comme dans Mail.app.
J'ai fait quelque chose de similaire à ce qu'a fait xtravar .
J'ai ajouté une vue en dehors de la hiérarchie des vues du
tableViewController
.Ensuite, j'ai utilisé le code suivant dans
tableView:numberOfRowsInSection:
:Fondamentalement, j'ai ajouté le en
emptyStateView
tant que sous-vue de l'tableView
objet. Comme les séparateurs chevaucheraient la vue, j'ai défini leur couleur surclearColor
. Pour revenir à la couleur de séparation par défaut, vous pouvez simplement la définir surnil
.la source
tableHeaderView
, et de m'assurer qu'il est redimensionné pour s'adapter .Selon Apple, utiliser un contrôleur de vue de conteneur est la bonne façon de le faire .
J'ai mis toutes mes vues d'état vides dans un Storyboard séparé. Chacun sous sa propre sous-classe UIViewController. J'ajoute du contenu directement sous leur vue racine. Si une action / un bouton est nécessaire, vous avez maintenant déjà un contrôleur pour le gérer.
Ensuite, il suffit d'instancier le contrôleur de vue souhaité à partir de ce Storyboard, de l'ajouter en tant que contrôleur de vue enfant et d'ajouter la vue de conteneur à la hiérarchie de tableView (sous-vue). Votre vue d'état vide pourra également faire défiler, ce qui vous convient et vous permet d'implémenter pull to refresh.
Lisez le chapitre «Ajout d'un contrôleur de vue enfant à votre contenu» pour obtenir de l'aide sur la façon de l'implémenter.
Assurez-vous simplement de définir le cadre de vue enfant comme
(0, 0, tableView.frame.width, tableView.frame.height)
et les choses seront centrées et alignées correctement.la source
Premièrement, les problèmes avec d'autres approches populaires.
Vue en arrière-plan
La vue d'arrière-plan ne se centre pas bien si vous deviez utiliser le cas simple de le définir comme un UILabel.
Cellules, en-têtes ou pieds de page pour afficher le message
Cela interfère avec votre code fonctionnel et introduit des cas extrêmes. Si vous voulez parfaitement centrer votre message, cela ajoute un autre niveau de complexité.
Faire rouler votre propre contrôleur de vue de table
Vous perdez les fonctionnalités intégrées, telles que refreshControl, et réinventez la roue. Restez fidèle à UITableViewController pour les meilleurs résultats maintenables.
Ajout de UITableViewController en tant que contrôleur de vue enfant
J'ai le sentiment que vous vous retrouverez avec des problèmes de contentInset dans iOS 7+ - et pourquoi compliquer les choses?
Ma solution
La meilleure solution que j'ai trouvée (et, certes, ce n'est pas l'idéal) est de créer une vue spéciale qui puisse être placée au-dessus d'une vue de défilement et agir en conséquence. Cela se complique évidemment dans iOS 7 avec la folie contentInset, mais c'est faisable.
Choses à surveiller:
Une fois que vous avez compris cela une fois dans une sous-classe UIView, vous pouvez l'utiliser pour tout - charger des spinners, désactiver des vues, afficher des messages d'erreur, etc.
la source
addSubView
elle est attachée à la vue tableau, ce qui pose toujours des problèmes avec la mise en page automatique.C'est la solution la meilleure et la plus simple.
la source
Afficher le message pour une liste vide, que ce soit son UITableView ou UICollectionView .
Coutumes:
OU:
N'oubliez pas: n'oubliez pas de supprimer l'étiquette du message au cas où les données viendraient après l'actualisation.
la source
Sélectionnez votre tableviewController Scene dans le storyboard
Faites glisser et déposez UIView Ajouter une étiquette avec votre message (par exemple: Aucune donnée)
créer une sortie d'UIView (par exemple, yournoDataView) sur votre TableViewController.
et dans viewDidLoad
self.tableView.backgroundView = votreNoDataView
la source
Utilisation de Swift 4.2
la source
Vous pouvez l'ajouter à votre classe de base.
Montrez-le comme ceci dans la classe sur l'obtention des données de l'API.
Cachez-le comme ça.
la source
Version Swift mais forme meilleure et plus simple. ** 3,0
J'espère que cela servira votre objectif ......
Dans votre UITableViewController.
Classe d'assistance avec fonction:
la source
Probablement pas la meilleure solution, mais je l'ai fait en mettant simplement une étiquette au bas de mon tableau et si les lignes = 0, je lui attribue du texte. Assez facile et réalise ce que vous essayez de faire avec quelques lignes de code.
J'ai deux sections dans mon tableau (emplois et écoles)
la source
Le moyen le plus simple et le plus rapide de le faire est de faire glisser une étiquette sur le panneau latéral sous tableView. Créez une sortie pour l'étiquette et la tableView et ajoutez une instruction if pour masquer et afficher l'étiquette et la table si nécessaire. Vous pouvez également ajouter tableView.tableFooterView = UIView (frame: CGRect.zero) à viewDidLoad () pour donner à une table vide l'impression qu'elle est masquée si la table et la vue d'arrière-plan ont la même couleur.
la source
J'ai apporté quelques modifications afin que nous n'ayons pas besoin de vérifier le décompte manuellement, j'ai également ajouté des contraintes pour l'étiquette afin que rien ne se passe mal quelle que soit la taille du message, comme indiqué ci-dessous:
Usage
la source
Ou vous pouvez également utiliser une bibliothèque légère personnalisable
SwiftEmptyState
la source