Eu tenho um UITableView que, em alguns casos, é legal estar vazio. Portanto, em vez de mostrar a imagem de plano de fundo do aplicativo, prefiro imprimir uma mensagem amigável na tela, como:
Esta lista está agora vazia
Qual é a maneira mais simples de fazer isso?
iphone
ios
uitableview
uiview
estado de
fonte
fonte
Respostas:
A propriedade backgroundView do UITableView é sua amiga.
Em
viewDidLoad
ou em qualquer lugar que vocêreloadData
deve determinar se a sua tabela está vazia ou não e atualize a propriedade backgroundView do UITableView com uma UIView contendo um UILabel ou apenas defina-a como nula. É isso aí.É claro que é possível fazer com que a fonte de dados do UITableView cumpra duas funções e retorne uma célula especial "list is empty", isso me parece uma ilusão. De repente,
numberOfRowsInSection:(NSInteger)section
é preciso calcular o número de linhas de outras seções que não foram solicitadas para garantir que elas também estejam vazias. Você também precisa criar uma célula especial que tenha a mensagem vazia. Além disso, não esqueça que você provavelmente precisará alterar a altura do seu celular para acomodar a mensagem vazia. Tudo isso é possível, mas parece um band-aid em cima do band-aid.fonte
backgroundView
propriedade oculta é o caminho a percorrer. ComDZNEmptyDataSet
, temos que usar o seuemptyDataSetSource
tableView.backgroundView!.userInteraction = true
após a linha que você definiutableView.backgroundView = constructMyViewWithButtons()
, ou como você o definiu.O mesmo que a resposta de Jhonston, mas eu a preferi como uma extensão:
Uso:
fonte
func numberOfSections(in tableView: UITableView) -> Int
métodoCom base nas respostas aqui, aqui está uma aula rápida que eu fiz que você pode usar no seu
UITableViewController
.No seu
UITableViewController
você pode chamar isso emnumberOfSectionsInTableView(tableView: UITableView) -> Int
Com uma pequena ajuda de http://www.appcoda.com/pull-to-refresh-uitableview-empty/
fonte
viewController.tableView.separatorStyle = .none
não é obrigatório.Eu recomendo a seguinte biblioteca: DZNEmptyDataSet
A maneira mais fácil de adicioná-lo ao seu projeto é usá-lo com Cocaopods assim:
pod 'DZNEmptyDataSet'
No seu TableViewController, adicione a seguinte declaração de importação (Swift):
Em seguida, certifique-se de seus conforma classe para o
DNZEmptyDataSetSource
eDZNEmptyDataSetDelegate
assim:No seu,
viewDidLoad
adicione as seguintes linhas de código:Agora tudo o que você precisa fazer para mostrar o estado vazio é:
Esses métodos não são obrigatórios, também é possível apenas mostrar o estado vazio sem um botão etc.
Para Swift 4
fonte
Uma maneira de fazer isso seria modificar sua fonte de dados para retornar
1
quando o número de linhas for zero e produzir uma célula de finalidade especial (talvez com um identificador de célula diferente) notableView:cellForRowAtIndexPath:
método.Isso pode ficar um pouco complicado se você tiver vários controladores de exibição de tabela que precisam manter, porque alguém se esquecerá de inserir uma verificação zero. Uma abordagem melhor é criar uma implementação separada de uma
UITableViewDataSource
implementação que sempre retorne uma única linha com uma mensagem configurável (vamos chamá-loEmptyTableViewDataSource
). Quando os dados gerenciados pelo seu controlador de exibição de tabela são alterados, o código que gerencia a alteração verifica se os dados estão vazios. Se não estiver vazio, configure seu controlador de exibição de tabela com sua fonte de dados regular; caso contrário, configure-o com uma instância doEmptyTableViewDataSource
que foi configurada com a mensagem apropriada.fonte
deleteRowsAtIndexPaths:withRowAnimation:
pois o número retornado dasnumberOfRowsInSection
necessidades corresponde ao resultado de $ numRows - $ linesDeleted.Eu tenho usado a mensagem titleForFooterInSection para isso. Não sei se isso é subótimo ou não, mas funciona.
fonte
return tableView.numberOfRowsInSection(section) == 0 ? "This list is now empty" : nil
Portanto, para uma solução mais segura:
e
UICollectionView
também:Solução mais genérica:
fonte
Só posso recomendar arrastar e soltar um UITextView dentro do TableView após as células. Faça uma conexão com o ViewController e oculte / exiba quando apropriado (por exemplo, sempre que a tabela for recarregada).
fonte
Usar o backgroundView é bom, mas não rola muito bem como no Mail.app.
Eu fiz algo semelhante ao que o xtravar fez.
Eu adicionei uma visualização fora da hierarquia da
tableViewController
.Então eu usei o seguinte código em
tableView:numberOfRowsInSection:
:Basicamente, eu adicionei o
emptyStateView
como uma subview dotableView
objeto. Como os separadores se sobrepõem à vista, defino sua cor comoclearColor
. Para voltar à cor padrão do separador, basta configurá-lo comonil
.fonte
tableHeaderView
e redimensionar para caber .Usar um Container View Controller é a maneira correta de fazê-lo, de acordo com a Apple .
Coloquei todas as minhas visualizações de estado vazias em um Storyboard separado. Cada um abaixo da sua própria subclasse UIViewController. Eu adiciono conteúdo diretamente na visualização raiz. Se qualquer ação / botão for necessária, agora você já possui um controlador para lidar com isso.
Depois, basta instanciar o controlador de exibição desejado a partir desse Storyboard, adicione-o como um controlador de exibição filho e adicione a exibição de contêiner à hierarquia do tableView (sub-exibição). Sua exibição de estado vazio também pode ser rolada, o que é bom e permite que você implemente pull to refresh.
Leia o capítulo 'Adicionando um controlador de exibição infantil ao seu conteúdo' para obter ajuda sobre como implementar.
Apenas certifique-se de definir o quadro de exibição filho como
(0, 0, tableView.frame.width, tableView.frame.height)
e as coisas serão centralizadas e alinhadas corretamente.fonte
Primeiro, os problemas com outras abordagens populares.
BackgroundView
A exibição de plano de fundo não é muito boa se você usar o simples caso de defini-la como um UILabel.
Células, cabeçalhos ou rodapés para exibir a mensagem
Isso interfere no seu código funcional e apresenta casos extremos estranhos. Se você deseja centralizar perfeitamente sua mensagem, isso adiciona outro nível de complexidade.
Rolando seu próprio controlador de exibição de tabela
Você perde a funcionalidade interna, como refreshControl, e reinventa a roda. Atenha-se ao UITableViewController para obter os melhores resultados de manutenção.
Adicionando UITableViewController como um controlador de exibição filho
Tenho a sensação de que você terminará com os problemas contentInset no iOS 7+ - além de por que complicar as coisas?
Minha solução
A melhor solução que eu encontrei (e, concedido, isso não é o ideal) é criar uma visualização especial que possa ficar no topo de uma visualização de rolagem e agir de acordo. Obviamente, isso fica complicado no iOS 7 com a loucura contentInset, mas é factível.
Itens a serem observados:
Depois de descobrir isso uma vez em uma subclasse do UIView, você pode usá-lo para tudo - carregar spinners, desativar visualizações, mostrar mensagens de erro etc.
fonte
addSubView
, é anexada à visualização da tabela, o que sempre causa problemas no layout automático.Esta é a melhor e mais simples solução.
fonte
Mostrar mensagem para lista vazia, seja seu UITableView ou UICollectionView .
Usos:
OU:
Lembre-se: Não esqueça de remover o rótulo da mensagem, caso os dados cheguem após a atualização.
fonte
Cena do controlador no storyboard
Arraste e solte UIView Adicione um marcador com sua mensagem (por exemplo: Sem dados)
crie uma saída do UIView (por exemplo, yournoDataView) no seu TableViewController.
e em viewDidLoad
self.tableView.backgroundView = yourNoDataView
fonte
Usando o Swift 4.2
fonte
Você pode adicionar isso à sua classe Base.
Mostre dessa forma na classe sobre como obter os dados da API.
Esconda assim.
fonte
Versão rápida, mas melhor e mais simples. ** 3,0
Espero que servidor seu propósito ......
No seu UITableViewController.
Classe auxiliar com função:
fonte
Provavelmente não é a melhor solução, mas fiz isso colocando um rótulo na parte inferior da minha tabela e, se as linhas = 0, atribuo-lhe algum texto. Muito fácil e consegue o que você está tentando fazer com algumas linhas de código.
Tenho duas seções na minha mesa (empregos e escolas)
fonte
A maneira mais fácil e rápida de fazer isso é arrastar um rótulo para o painel lateral sob tableView. Crie uma saída para o rótulo e o tableView e adicione uma instrução if para ocultar e mostrar o rótulo e a tabela conforme necessário. Como alternativa, você pode adicionar tableView.tableFooterView = UIView (frame: CGRect.zero) a isto viewDidLoad () para dar a uma tabela vazia a percepção de que ela está oculta se a tabela e a exibição em segundo plano tiverem a mesma cor.
fonte
Fiz algumas alterações para não precisarmos verificar a contagem manualmente, também adicionei restrições para o rótulo para que nada dê errado, não importa o tamanho da mensagem, como mostrado abaixo:
Uso
fonte
Ou, como alternativa, você pode usar uma biblioteca leve e personalizável
SwiftEmptyState
fonte