Pelo que entendi, você deseja:
- Crie uma célula no IB que possa ser usada em várias cenas do storyboard.
- Configure segues de storyboard exclusivos a partir dessa célula, dependendo da cena em que a célula está.
Infelizmente, atualmente não há como fazer isso. Para entender por que suas tentativas anteriores não funcionaram, você precisa entender mais sobre como as células de exibição de tabela de protótipos e storyboards funcionam. (Se você não se importa com o motivo pelo qual essas outras tentativas não funcionaram, fique à vontade para sair agora. Não tenho nenhuma solução mágica para você, além de sugerir que você registre um bug.)
Um storyboard é, em essência, não muito mais do que uma coleção de arquivos .xib. Quando você carrega um controlador de exibição de tabela que possui algumas células protótipo de um storyboard, eis o que acontece:
- Cada célula protótipo é na verdade sua própria mini ponta embutida. Portanto, quando o controlador de exibição de tabela está sendo carregado, ele percorre cada uma das pontas e chamadas da célula do protótipo
-[UITableView registerNib:forCellReuseIdentifier:]
.
- A visualização da tabela solicita ao controlador as células.
- Você provavelmente liga
-[UITableView dequeueReusableCellWithIdentifier:]
Quando você solicita uma célula com um determinado identificador de reutilização, ela verifica se possui uma ponta registrada. Se isso acontecer, ele instancia uma instância dessa célula. Isso é composto pelas seguintes etapas:
- Veja a classe da célula, conforme definido na ponta da célula. Ligue
[[CellClass alloc] initWithCoder:]
.
- O
-initWithCoder:
método passa e adiciona subvisões e define propriedades que foram definidas na ponta. ( IBOutlet
provavelmente também estão ligados aqui, embora eu não tenha testado; pode acontecer em -awakeFromNib
)
Você configura seu celular da maneira que desejar.
O importante a ser observado aqui é que há uma distinção entre a classe da célula e a aparência visual da célula. Você pode criar duas células de protótipo separadas da mesma classe, mas com suas subvisões dispostas de maneira completamente diferente. De fato, se você usar os UITableViewCell
estilos padrão , é exatamente isso que está acontecendo. O estilo "Padrão" e o estilo "Legenda", por exemplo, são ambos representados pela mesma UITableViewCell
classe.
Isso é importante : A classe da célula não tem uma correlação individual com uma hierarquia de exibição específica . A hierarquia de visualizações é determinada inteiramente pelo conteúdo da célula protótipo que foi registrada neste controlador em particular.
Observe também que o identificador de reutilização da célula não foi registrado em algum dispensário global de células. O identificador de reutilização é usado apenas no contexto de uma única UITableView
instância.
Dada essa informação, vejamos o que aconteceu nas suas tentativas acima.
No Controlador nº 1, adicionei uma célula protótipo, defina a classe como minha subclasse UITableViewCell, defina o ID de reutilização, adicione os rótulos e os conecte às saídas da classe. No Controlador nº 2, adicionou uma célula protótipo vazia, defina-a na mesma classe e reutilize o ID como antes. Quando é executado, os rótulos nunca aparecem quando as células são mostradas no Controlador nº 2. Funciona bem no Controlador nº 1.
Isso é esperado. Embora as duas células tenham a mesma classe, a hierarquia de exibição que foi passada para a célula no Controlador nº 2 foi totalmente desprovida de subvisões. Então você tem uma célula vazia, que é exatamente o que você coloca no protótipo.
Projetou cada tipo de célula em um NIB diferente e conectado à classe de célula apropriada. No storyboard, adicionei uma célula protótipo vazia e defina sua classe e ID de reutilização para se referir à minha classe de célula. Nos métodos viewDidLoad dos controladores, registrou esses arquivos NIB para o ID de reutilização. Quando mostradas, as células nos dois controladores estavam vazias como o protótipo.
Novamente, isso é esperado. O identificador de reutilização não é compartilhado entre cenas ou pontas do storyboard, portanto, o fato de todas essas células distintas terem o mesmo identificador de reutilização não faz sentido. A célula que você voltar da tableview terá uma aparência que corresponde à célula protótipo na cena do storyboard.
Essa solução estava próxima, no entanto. Como você observou, você poderia simplesmente chamar de forma programática -[UITableView registerNib:forCellReuseIdentifier:]
, passando o que UINib
continha a célula, e recuperaria a mesma célula. (Isso não ocorre porque o protótipo estava "substituindo" a ponta; você simplesmente não havia registrado a ponta na tableview, por isso ainda estava olhando a ponta incorporada no storyboard.) Infelizmente, há uma falha nessa abordagem - não há como conectar segues de storyboard a uma célula em uma ponta independente.
Os protótipos mantidos nos dois controladores esvaziam e definem a classe e reutilizam o ID para a minha classe de célula. Construiu a interface do usuário das células inteiramente em código. As células funcionam perfeitamente em todos os controladores.
Naturalmente. Felizmente, isso não é surpreendente.
Então, é por isso que não funcionou. Você pode projetar suas células em pontas independentes e usá-las em várias cenas de storyboard; no momento, você não pode conectar seques de storyboard a essas células. Felizmente, você aprendeu alguma coisa no processo de ler isso.
Apesar da ótima resposta de BJ Homer, sinto que tenho uma solução. No que diz respeito aos meus testes, ele funciona.
Conceito: Crie uma classe customizada para a célula xib. Lá, você pode esperar por um evento de toque e executar as etapas programaticamente. Agora, tudo o que precisamos é uma referência ao controlador que está executando o Segue. Minha solução é configurá-lo
tableView:cellForRowAtIndexPath:
.Exemplo
Eu tenho uma
DetailedTaskCell.xib
célula de tabela que eu gostaria de usar em várias visualizações de tabela:Há uma classe personalizada
TaskGuessTableCell
para essa célula:É aqui que a mágica acontece.
Eu tenho vários Segues mas todos eles têm o mesmo nome:
"FinishedTask"
. Se você precisar ser flexível aqui, sugiro adicionar outra propriedade.O ViewController fica assim:
Pode haver maneiras mais elegantes de conseguir o mesmo, mas - funciona! :)
fonte
-setSelected:
a célula e acionando o segue somente ao fazer a transição deNO
paraYES
.setSelected:
, BJ. Obrigado. Na verdade, é uma solução deselegante ( parece errada), mas, ao mesmo tempo, funciona, então estou usando até que isso seja corrigido (ou que algo mude no tribunal da Apple).Eu estava procurando por isso e encontrei a resposta de Richard Venable. Funciona para mim.
fonte
BJ Homer deu uma excelente explicação sobre o que está acontecendo.
Do ponto de vista prático, eu acrescentaria que, como você não pode ter células como xibs E conectar sequências, a melhor opção é ter a célula como xib - as transições são muito mais fáceis de manter do que os layouts e as propriedades das células em vários lugares , e seus seguidores provavelmente serão diferentes de seus diferentes controladores de qualquer maneira. Você pode definir o segue diretamente do seu controlador de exibição de tabela para o próximo controlador e executá-lo no código. .
Uma observação adicional é que ter o seu celular como um arquivo xib separado impede que você seja capaz de conectar quaisquer ações etc. diretamente ao controlador de exibição de tabela (eu não resolvi isso de qualquer maneira - você não pode definir o proprietário do arquivo como algo significativo ) Estou contornando isso definindo um protocolo ao qual o controlador de exibição de tabela da célula deve estar em conformidade e adicionando o controlador como uma propriedade fraca, semelhante a um delegado, no cellForRowAtIndexPath.
fonte
Swift 3
BJ Homer deu uma excelente explicação: isso me ajuda a entender o conceito. Para
make a custom cell reusable in storyboard
, que pode ser usado em qualquer TableViewController, temos que nosmix the Storyboard and xib
aproximar. Suponha que tenhamos uma célula nomeada comoCustomCell
qual deve ser usada noTableViewControllerOne
eTableViewControllerTwo
. Eu estou fazendo isso em etapas.1. Arquivo> Novo> Clique em Arquivo> Selecionar Classe do Cocoa Touch> clique em Avançar> Nome da sua classe (por exemplo
CustomCell
)> selecione Subclasse como UITableVieCell> Marque a caixa de seleção também criar arquivo XIB e pressione Avançar.2. Personalize a célula como desejar e defina o identificador no inspetor de atributos para célula, aqui definiremos como
CellIdentifier
. Esse identificador será usado no seu ViewController para identificar e reutilizar a célula.3. Agora só temos que
register this cell
no nosso ViewControllerviewDidLoad
. Não há necessidade de nenhum método de inicialização.4. Agora podemos usar essa célula personalizada em qualquer tableView.
Em TableViewControllerOne
fonte
Eu encontrei uma maneira de carregar a célula para o mesmo VC, não testado para os seguintes. Isso pode ser uma solução alternativa para criar a célula em uma ponta separada
Digamos que você tenha uma VC e 2 tabelas e deseja criar uma célula no storyboard e usá-la nas duas tabelas.
(por exemplo: uma tabela e um campo de pesquisa com um UISearchController com uma tabela para resultados e você deseja usar a mesma célula em ambos)
Quando o controlador solicitar a célula, faça o seguinte:
E aqui você tem seu celular do storyboard
fonte
tableView:cellForRowAtIndexPath:
).