Pergunta

Eu sou capaz de projetar UITableViewCells personalizados e carregá-los muito bem usando a técnica descrita no tópico encontradas em http://forums.macrumors.com/showthread.php?t=545061 . No entanto, usando esse método não permite inicializar o celular com um reuseIdentifier que significa que você tem que criar inteiras novas instâncias de cada célula em cada chamada. Alguém descobriu uma boa maneira de ainda cache em particular tipos de células para reutilizações, mas ainda ser capaz de projetá-los no Interface Builder?

Foi útil?

Solução

Apenas implementar um método com a assinatura do método apropriado:

- (NSString *) reuseIdentifier {
  return @"myIdentifier";
}

Outras dicas

Na verdade, desde que você está construindo a célula na Interface Builder, basta definir o identificador de reutilização lá:

IB_reuse_identifier

Ou se você estiver executando o Xcode 4, verifique a guia Atributos inspector:

enter descrição da imagem aqui

(Edit: Após o seu XIB é gerado pelo XCode, ele contém um UIView vazio, mas precisamos de um UITableViewCell; então você tem que remover manualmente o UIView e inserir um celular Table View Claro, IB não vai mostrar qualquer UITableViewCell. parâmetros para um UIView.)

Agora, no iOS 5 há um método UITableView apropriado para isso:

- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier

Não me lembro onde eu encontrei este código originalmente, mas está trabalhando muito bem para mim até agora.

- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"CustomTableCell";
    static NSString *CellNib = @"CustomTableCellView";

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
        cell = (UITableViewCell *)[nib objectAtIndex:0];
    }

    // perform additional custom work...

    return cell;
}

Configuração Exemplo Interface Builder ...

text alt

Observe a resposta que dei a esta pergunta:

É possível projetar subclasses NSCell na interface Builder?

Não é apenas possível projetar um UITableViewCell no IB, é desejável porque senão toda a fiação manual e colocação de vários elementos é muito tedioso. Performaance é bom, desde que você tome cuidado para fazer todos os elementos opacos quando possível. O reuseID é definido em IB para as propriedades do UITableViewCell, então você usa o ID reutilização correspondente no código ao tentar dequeue.

Eu também ouvi de alguns dos apresentadores na WWDC do ano passado que você não deve fazer células visualizar a tabela em IB, mas é uma carga de beliche.

A partir de iOS cerca de 4.0, há instruções específicas nos docs iOS que fazem este trabalho super-rápido:

http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7

Vá até onde ele fala sobre subclasse UITableViewCell.

Aqui é uma outra opção:

NSString * cellId = @"reuseCell";  
//...
NSArray * nibObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomTableCell" owner:nil options:nil];

for (id obj in nibObjects)
{
    if ([obj isKindOfClass:[CustomTableCell class]])
    {
        cell = obj;
        [cell setValue:cellId forKey:@"reuseIdentifier"];
        break;
    }
}

eu crio minhas células de exibição personalizado de uma forma similar - só que eu conectar o celular através de um IBOutlet

.

A abordagem [nib objectAt...] é susceptível a modificações de posições de itens na matriz.

A abordagem UIViewController é bom -. Só tentei, e ele funciona bom o suficiente

Mas ...

Em todos os casos o construtor initWithStyle não é chamado, por isso não inicialização padrão é feito.

Eu li vários lugares sobre o uso initWithCoder ou awakeFromNib, mas não há provas conclusivas de que qualquer um destes é o caminho certo.

Além de chamar explicitamente algum método de inicialização no método cellForRowAtIndexPath eu não encontrei uma resposta para isso ainda.

Um tempo atrás eu encontrei um ótimo post sobre este tema em blog.atebits.com , e desde então começou a usar classe Loren Brichter ABTableViewCell fazer todos os meus UITableViewCells.

Você acaba com uma UIView recipiente simples para colocar todos os seus widgets, e rolagem é muito rápido.

Hope isso é útil.

Esta técnica também funciona e não requer um ivar desagradável em seu controlador de exibição para gerenciamento de memória. Aqui, a vida de célula personalizado mesa de vista em um xib chamado "CustomCell.xib".

 static NSData *sLoadedCustomCell = nil;

 cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
 if (cell == nil) 
 {
   if (sLoadedCustomCell == nil) 
   {        
      // Load the custom table cell xib
      // and extract a reference to the cell object returned
      // and cache it in a static to avoid reloading the nib again.

      for (id loadedObject in [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:nil options:nil]) 
      {
        if ([loadedObject isKindOfClass:[UITableViewCell class]]) 
        {
          sLoadedCustomCell = [[NSKeyedArchiver archivedDataWithRootObject: loadedObject] retain];
          break;
        }
    }
    cell = (UITableViewCell *)[NSKeyedUnarchiver unarchiveObjectWithData: sLoadedCustomCell];
  }

método Louis trabalhou para mim. Este é o código que usei para criar o UITableViewCell do nib:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{   
    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellId"];

    if (cell == nil) 
    {
        UIViewController *c = [[UIViewController alloc] initWithNibName:@"CustomCell" bundle:nil];
        cell = (PostCell *)c.view;
        [c release];
    }

    return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *simpleTableIdentifier = @"CustomCell";

CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}         

return cell;
}

A solução gustavogb não funciona para mim, o que eu tentei é:

ChainesController *c = [[ChainesController alloc] initWithNibName:@"ChainesController" bundle:nil];
[[NSBundle mainBundle] loadNibNamed:@"ChaineArticleCell" owner:c options:nil];
cell = [c.blogTableViewCell retain];
[c release];

Parece que funciona. O blogTableViewCell é o IBOutlet para a célula e ChainesController é o dono do arquivo.

De docs uitableview sobre dequeueWithReuseIdentifier: ". A cadeia que identifica o objeto célula para ser reutilizado Por padrão, o identificador da célula reutilizável é seu nome de classe, mas você pode alterá-lo para qualquer valor arbitrário"

Overriding -reuseIdentifer si mesmo é arriscado. O que acontece se você tem duas subclasses de sua subclasse celular e usar ambos em uma única exibição de tabela? Se eles enviar a chamada reutilização identificador para Super você desenfileirar uma célula do tipo errado .............. Eu acho que você precisa substituir o método reuseIdentifier, mas tê-lo retornar um identificador suplantado corda. Ou, se não tiver sido especificado, tê-lo retornar a classe como um string.

Por que vale a pena, eu pedi um engenheiro iPhone sobre isso em um dos iPhone Tech Talks. Sua resposta foi: "Sim, é possível usar IB para criar células. Mas não. Por favor, não."

Eu segui as instruções da Apple como ligados por Ben Mosher (graças!), Mas descobriu que a Apple omitido um ponto importante. O objeto que eles projetam em IB é apenas um UITableViewCell, como é a variável que carregar a partir dele. Mas se você realmente configurá-lo como uma subclasse personalizada de UITableViewCell e gravar os arquivos de código para a subclasse, você pode escrever declarações IBOutlet e métodos IBAction no código e fio-los aos seus elementos personalizados em IB. Então, não há necessidade de usar vista tags para acessar esses elementos e você pode criar qualquer tipo de célula louco que quiser. É de Cocoa Touch céu.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top