Você está encontrando o efeito colateral de um novo recurso fantástico nas Tableviews do iOS8: Automatic Row Heights.
No iOS 7, você tinha linhas de tamanho fixo (definido com tableView.rowHeight
) ou escrevia um código para calcular a altura de suas células e o retornava tableView:heightForRowAtIndexPath
. Escrever código para o cálculo da altura de uma célula pode ser bastante complexo se você tiver várias visualizações em sua célula e tiver diferentes alturas a serem consideradas em tamanhos de fonte diferentes. Acrescente Dynamic Type e o processo foi um pé no saco.
No iOS 8, você ainda pode fazer o acima, mas agora a altura das linhas pode ser determinada pelo iOS, desde que você tenha configurado o conteúdo da sua célula usando o Layout automático. Esse é um grande benefício para os desenvolvedores, pois conforme o tamanho da fonte dinâmica muda ou o usuário modifica o tamanho do texto usando as Configurações de Acessibilidade, sua interface do usuário pode ser adaptável ao novo tamanho. Isso também significa que, se você tiver um UILabel que pode ter várias linhas de texto, sua célula poderá aumentar para acomodar aquelas quando as células precisarem e diminuir quando não precisar, para que não haja espaço em branco desnecessário.
A mensagem de aviso exibida está informando que não há restrições suficientes em sua célula para o Layout automático para informar a visualização da tabela sobre a altura da célula.
Para usar a altura dinâmica da célula, que, juntamente com as técnicas já mencionadas por outros pôsteres, também eliminará essa mensagem, é necessário garantir que sua célula tenha restrições suficientes para vincular os itens da interface do usuário à parte superior e inferior da célula. Se você já usou o Layout automático antes, provavelmente está acostumado a definir restrições Top + Leading, mas a altura da linha dinâmica também exige restrições inferiores.
O passe de layout funciona assim, o que ocorre imediatamente antes de uma célula ser exibida na tela, de maneira just-in-time:
As dimensões do conteúdo com tamanhos intrínsecos são calculadas. Isso inclui UILabels e UIImageViews, onde suas dimensões são baseadas no texto ou UIImages que eles contêm, respectivamente. Ambas as visualizações consideram sua largura conhecida (porque você definiu restrições para as bordas à direita / à direita, definiu larguras explícitas ou usou restrições horizontais que eventualmente revelam uma largura de um lado para o outro). Digamos que um rótulo tenha um parágrafo de texto ("número de linhas" é definido como 0 para que ele seja quebrado automaticamente), ele pode ter apenas 310 pontos de diâmetro e, portanto, está determinado a ter 120 pontos de altura no tamanho da fonte atual.
A interface do usuário é definida de acordo com suas restrições de posicionamento. Há uma restrição na parte inferior do rótulo que se conecta à margem inferior da célula. Como o rótulo cresceu para 120 pontos de altura e, como está vinculado à parte inferior da célula pela restrição, ele deve empurrar a célula "para baixo" (aumentando a altura da célula) para satisfazer a restrição que diz "parte inferior da o rótulo está sempre a uma distância padrão da parte inferior da célula.
A mensagem de erro que você relatou ocorre se essa restrição inferior estiver faltando; nesse caso, não há nada para "empurrar" a parte inferior da célula para longe da parte superior da célula, que é a ambiguidade relatada: sem nada para empurrar a parte inferior no topo, a célula entra em colapso. Mas o Auto Layout também detecta isso e volta a usar a altura da linha padrão.
Para o que vale a pena e, principalmente, para ter uma resposta arredondada, se você implementar as alturas de linha dinâmicas baseadas no Auto Layout do iOS 8, implemente tableView:estimatedHeightForRowAtIndexPath:
. Esse método de estimativa pode usar valores aproximados para suas células e será chamado quando a exibição da tabela for carregada inicialmente. Ajuda o UIKit a desenhar coisas como a barra de rolagem, que não pode ser desenhada, a menos que a tableview saiba quanto conteúdo pode percorrer, mas não precisa de tamanhos totalmente precisos, pois é apenas uma barra de rolagem. Isso permite que o cálculo da altura real da linha seja adiado até o momento em que a célula é necessária, o que é menos intensivo em termos de computação e permite que o seu UITableView seja apresentado mais rapidamente.