A pergunta é simples: como você carrega UITableViewCell
arquivos personalizados do Xib? Isso permite que você use o Interface Builder para projetar suas células. A resposta aparentemente não é simples devido a problemas de gerenciamento de memória. Este tópico menciona o problema e sugere uma solução, mas é anterior ao lançamento do NDA e não possui código. Aqui está um longo tópico que discute o problema sem fornecer uma resposta definitiva.
Aqui está um código que eu usei:
static NSString *CellIdentifier = @"MyCellIdentifier";
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = (MyCell *)[nib objectAtIndex:0];
}
Para usar esse código, crie MyCell.m / .h, uma nova subclasse de UITableViewCell
e adicione IBOutlets
os componentes desejados. Em seguida, crie um novo arquivo "Empty XIB". Abra o arquivo Xib no IB, adicione um UITableViewCell
objeto, defina seu identificador como "MyCellIdentifier" e defina sua classe como MyCell e adicione seus componentes. Por fim, conecte-o IBOutlets
aos componentes. Observe que não definimos o proprietário do arquivo no IB.
Outros métodos defendem a configuração do Proprietário do arquivo e avisam sobre vazamentos de memória se o Xib não for carregado por meio de uma classe de fábrica adicional. Testei o acima em Instrumentos / Vazamentos e não vi vazamentos de memória.
Então, qual é a maneira canônica de carregar células do Xibs? Nós definimos o proprietário do arquivo? Nós precisamos de uma fábrica? Em caso afirmativo, como é o código da fábrica? Se houver várias soluções, vamos esclarecer os prós e contras de cada uma delas ...
fonte
Respostas:
Aqui estão dois métodos que o autor original declara ter sido recomendado por um engenheiro do IB .
Veja a publicação real para mais detalhes. Eu prefiro o método 2, pois parece mais simples.
Método 1:
Método 2:
Atualização (2014): O método 2 ainda é válido, mas não há mais documentação para ele. Costumava estar nos documentos oficiais mas agora é removido em favor dos storyboards.
Publiquei um exemplo de trabalho no Github:
https://github.com/bentford/NibTableCellExample
editar para Swift 4.2
fonte
A solução certa é esta:
fonte
Registro
Após o iOS 7, esse processo foi simplificado para ( swift 3.0 ):
Retirar da fila
E mais tarde, desenfileirado usando ( swift 3.0 ):
A diferença é que esse novo método não apenas remove a fila da célula, mas também cria se não existe (isso significa que você não precisa fazer
if (cell == nil)
travessuras), e a célula está pronta para uso, como no exemplo acima.E, é claro, o tipo de classe associada da célula é o que você definiu no arquivo .xib para a
UITableViewCell
subclasse ou, alternativamente, usando o outro método de registro.Configuração
Idealmente, suas células já foram configuradas em termos de aparência e posicionamento do conteúdo (como rótulos e visualizações de imagens) quando você as registrou e no
cellForRowAtIndexPath
método que você simplesmente as preenche.Todos juntos
E, claro, tudo isso está disponível no ObjC com os mesmos nomes.
fonte
[self.tableView registerNib:[UINib nibWithNibName:@"BlaBlaTableViewCell" bundle:nil] forCellReuseIdentifier:kCellIdentifier];
Tomou a resposta de Shawn Craver e a limpou um pouco.
BBCell.h:
BBCell.m:
Faço todas as subclasses de BBCell do meu UITableViewCell e substituo o padrão
com:
fonte
Eu usei o método # 2 de Bentford :
Funciona, mas cuidado com as conexões com o Proprietário do arquivo no seu arquivo .xib UITableViewCell personalizado.
Ao passar
owner:self
seuloadNibNamed
extrato, você defineUITableViewController
como o proprietário do arquivoUITableViewCell
.Se você arrastar e soltar no arquivo de cabeçalho no IB para configurar ações e saídas, ele será configurado como Proprietário do arquivo por padrão.
Em
loadNibNamed:owner:options
, o código da Apple tentará definir propriedades no seuUITableViewController
, já que esse é o proprietário. Mas como você não possui essas propriedades definidas, obtém um erro ao ser compatível com a codificação do valor-chave :Se um evento for acionado, você receberá uma NSInvalidArgumentException:
Uma solução fácil é apontar as conexões do Interface Builder para o
UITableViewCell
proprietário do arquivo, em vez do:fonte
Decidi postar porque não gosto de nenhuma dessas respostas - as coisas sempre podem ser mais simples e essa é de longe a maneira mais concisa que encontrei.
1. Construa seu Xib no Interface Builder como quiser
2. Na subclasse UIViewController ou UITableViewController
3. Na sua classe MyTableViewCellSubclass
fonte
Se você estiver usando o Interface Builder para criar células, verifique se configurou o Identificador no Inspetor. Em seguida, verifique se é o mesmo ao chamar dequeueReusableCellWithIdentifier.
Esqueci-me acidentalmente de definir alguns identificadores em um projeto pesado de tabelas, e a mudança de desempenho foi como dia e noite.
fonte
Carregar UITableViewCells de XIBs economiza muito código, mas geralmente resulta em velocidade de rolagem horrível (na verdade, não é o XIB, mas o uso excessivo de UIViews que causa isso).
Eu sugiro que você dê uma olhada nisso: Referência de link
fonte
Aqui está o método de classe que eu tenho usado para criar células personalizadas a partir de XIBs:
Em seguida, no XIB, defino o nome da classe e reutilizo o identificador. Depois disso, posso chamar esse método no meu controlador de exibição em vez do
É rápido o suficiente e está sendo usado em dois dos meus aplicativos de remessa. É mais confiável do que ligar
[nib objectAtIndex:0]
e, pelo menos em minha opinião, mais confiável do que o exemplo de Stephan Burlot, porque você garante apenas uma visualização de um XIB do tipo certo.fonte
Solução correta é esta
fonte
Recarregar o NIB é caro. Melhor carregá-lo uma vez e instanciar os objetos quando precisar de uma célula. Observe que você pode adicionar UIImageViews etc. à ponta, mesmo várias células, usando este método (o iOS5 "registerNIB" da Apple permite apenas um objeto de nível superior - Bug 10580062 "iOS5 tableView registerNib: excessivamente restritivo"
Então, meu código está abaixo - você lê o NIB uma vez (na inicialização como eu fiz ou no viewDidload - seja o que for. A partir de então, você instancia a ponta em objetos e escolhe o que você precisa. Isso é muito mais eficiente do que carregar a ponta de novo e de novo.
fonte
Verifique isto - http://eppz.eu/blog/custom-uitableview-cell/ - maneira realmente conveniente usando uma classe minúscula que termina uma linha na implementação do controlador:
fonte
A maneira correta de fazer isso é criar uma implementação, cabeçalho e XIB da subclasse UITableViewCell. No XIB, remova todas as visualizações e adicione uma célula da tabela. Defina a classe como o nome da subclasse UITableViewCell. Para o proprietário do arquivo, torne-o o nome da classe da subclasse UITableViewController. Conecte o proprietário do arquivo à célula usando a tomada tableViewCell.
No arquivo de cabeçalho:
No arquivo de implementação:
fonte
O que faço para isso é declarar um
IBOutlet UITableViewCell *cell
na sua classe de controlador. Em seguida, chame oNSBundle loadNibNamed
método de classe, que alimentará oUITableViewCell
a célula declarada acima.Para o xib, criarei um xib vazio e adicionei o
UITableViewCell
objeto no IB, onde ele pode ser configurado conforme necessário. Essa visualização é então conectada à célulaIBOutlet
na classe do controlador.Adições ao NSBundle loadNibNamed (login no ADC)
artigo de cocoawithlove.com de onde parti do conceito (obtenha o aplicativo de exemplo de números de telefone)
fonte
Crie sua própria
AbcViewCell
subclasse de classe personalizada emUITableViewCell
(Verifique se o nome do arquivo da classe e o nome do arquivo da ponta são os mesmos)Crie este método de classe de extensão.
Use-o.
let cell: AbcViewCell = UITableViewCell.fromNib()
fonte
Primeiro importe seu arquivo de célula personalizado
#import "CustomCell.h"
e, em seguida, altere o método delegate, conforme mencionado abaixo:fonte
No Swift 4.2 e no Xcode 10
Eu tenho três arquivos de célula XIB
no ViewDidLoad registre seus arquivos XIB assim ...
Esta é a primeira abordagem
A segunda abordagem registra diretamente os arquivos XIB no cellForRowAt indexPath:
Esta é a minha função de delegar tableview
fonte
Aqui está o meu método para isso: Carregando UITableViewCells personalizados a partir de arquivos XIB ... Outro método
A idéia é criar uma subclasse SampleCell
UITableViewCell
com umaIBOutlet UIView *content
propriedade e uma propriedade para cada subvisão personalizada que você precisa configurar a partir do código. Em seguida, crie um arquivo SampleCell.xib. Nesse arquivo de ponta, altere o proprietário do arquivo para SampleCell. Adicione um conteúdoUIView
dimensionado para atender às suas necessidades. Adicione e configure todas as subvisões (etiqueta, visualizações de imagem, botões, etc.) que você deseja. Por fim, vincule a exibição do conteúdo e as subvisões ao proprietário do arquivo.fonte
Aqui está uma abordagem universal para registrar células em
UITableView
:Explicação:
Reusable
O protocolo gera o ID da célula a partir do nome da classe. Certifique-se de seguir a convenção:cell ID == class name == nib name
.UITableViewCell
está em conformidade com oReusable
protocolo.UITableView
A extensão abstrai a diferença no registro de células via ponta ou classe.Exemplo de uso:
fonte
Não sei se existe uma maneira canônica, mas aqui está o meu método:
E use este código:
No seu exemplo, usando
pode quebrar se a Apple alterar a ordem dos itens no xib.
fonte
fonte
Esta extensão requer o Xcode7 beta6
Crie um arquivo Xib que contenha apenas 1 UITableViewCell personalizado.
Carregue-o.
fonte
fonte