Detectou um caso em que restrições sugerem ambiguamente uma altura zero

120

Depois de atualizar para o Xcode 6.1 beta 2, quando executo meu aplicativo que contém células tableview, o assistente de depuração diz:

Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.

Antes, quando eu usava o Xcode 5 nesse projeto, eu recebia alguns erros, mas esses desapareceram desde a atualização. Não tenho outros erros ou avisos agora. Eu já tentei ajustar os tamanhos de todas as células do tableview e também tentei usar a altura padrão, mas ainda recebo o mesmo aviso:

Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.

Também li todos os tópicos semelhantes sobre isso, mas nenhuma de suas soluções ajuda. Quando eu testo o aplicativo com o simulador, ele funciona bem, exceto que as imagens que deveriam estar nas células tableView não estão lá.

David E
fonte
2
Estou recebendo o mesmo erro para a célula de exibição de coleção. O que eu faço para isso. Alguma sugestão.
Python #
Talvez você deve verificar se você já adicionou o arquivo xib ao alvo stackoverflow.com/a/26870331/1418457
onmyway133
Isso aconteceu comigo no iOS 8.1, mas não no iOS 8.4. Se você especificou a altura, acho que é apenas um bug do Xcode.
samwize

Respostas:

126

Três coisas conseguiram silenciar esse aviso até agora. Você pode escolher o mais conveniente para você. Nada bonito embora.

  • Para configurar a altura da célula padrão em viewDidLoad

    self.tableView.rowHeight = 44;
  • Vá para o storyboard e altere a altura da linha na visualização da tabela para algo diferente de 44.

  • Para implementar o método delegado do tableview heightForRowAtIndexPath

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return 44;
    }
    

Esquisito.

Viktor Kucera
fonte
Eu também tentei usar o seu método, mas preciso adicionar uma propriedade @ para rowHeight, mas não sei o tipo de objeto correto a ser usado.
David E
Talvez eu não tenha recebido sua nota, mas rowHeight é uma propriedade do UITableView. Basta conectar sua mesa a uma tomada e pronto.
Viktor Kucera
4
Isso ocorre porque, se você mantiver o valor de 44pt no IB, ele considerará que deseja usar células de dimensionamento automático. stackoverflow.com/questions/25888126/... (mas, sim, este é um comportamento estranho, na verdade)
Guillaume Algis
Aparentemente, eu tinha dois métodos viewDidLoad e coloquei self.tableView.rowHeight = 44;o errado. O erro foi embora! graças
David E
Obrigado Guillaume Algis por deixar isso mais claro. Ainda é muito assustador.
Viktor Kucera
216

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:

  1. 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.

  2. 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.

Woodster
fonte
3
Esta é uma ótima explicação para o motivo principal deste aviso. Muito pelo seu tempo, Woodster!
Golden Thumb
4
Como o que Woodster disse, senti falta da parte inferior das restrições. Quando adicionado, meu problema foi resolvido.
Golden Thumb
Depois de tentar quase 20 coisas, este é o único que funcionou!
Julio Rodrigues
Este homem acertou em cheio! Ele merece e voto positivo e esta deve ser a resposta aceita. +1
caribbean
1
Consulte esta resposta stackoverflow.com/a/29565073/4080860 para descobrir qual célula está faltando restrições.
hhanesand
11

Eu tive esse problema depois de criar um personalizado UITableViewCelle adicionar minhas subvisões à célula em vez de à sua contentView.

ABakerSmith
fonte
10

Para resolver isso sem um método programático, ajuste a altura da linha da exibição da tabela no Inspetor de tamanhos do storyboard.

insira a descrição da imagem aqui

Anconia
fonte
A melhor solução para mim porque é usar os materiais do storyboard em vez de linhas para código.
ZYC
6

Este é um problema de pagamento automático. Verifique se suas subvisões possuem todas as restrições. Para mim, a restrição inferior estava faltando para o Label Title na célula. Quando acrescentei isso, o aviso foi embora e tudo apareceu perfeitamente.

Alok
fonte
Não sei por que isso foi prejudicado, pois é uma resposta perfeitamente boa. Veja aqui para ajuda em descobrir qual célula está tendo problemas para ser colocado para fora stackoverflow.com/a/29565073/4080860
hhanesand
5

Basta ativar células de exibição de tabela de dimensionamento automático

   tableView.estimatedRowHeight = 85.0
   tableView.rowHeight = UITableViewAutomaticDimension

E certifique-se de que você adicionou restrições em todos os lados de UITableViewCellas-

insira a descrição da imagem aqui

Jack
fonte
Na verdade, o aviso desapareceu quando desabilitei as células de auto-dimensionamento de tableview.
turingtested 26/09/18
@turingtested, você deve ativar a célula de tableview de dimensionamento automático para dar suporte em vários dispositivos.
Jack
Concorde, mas leia a pergunta original. O que eu quis dizer foi que sua solução sugerida não funcionou, pelo menos não para mim.
turingtested
FYI UITableViewAutomaticDimensionfoi renomeado paraUITableView.automaticDimension
atineoSE
5

Se você estiver usando célula estática ou célula dinâmica, basta adicionar alguma altura da linha à exibição da tabela na tabela do inspetor e desmarcar o automático no lado direito da altura da linha, é isso que você deixará de receber esse aviso.insira a descrição da imagem aqui

Amit Verma
fonte
Achei o oposto mais eficaz: defina uma altura estimada explícita e permita que a altura da linha seja automática.
NRitH 04/04/19
4

Recebi este aviso hoje. Aqui está o que o fez desaparecer para mim (no construtor de interfaces)

1. Defina o campo de altura da linha para a visualização da tabela como algo diferente de 44 2 Defina o campo de altura da linha para a célula tableView como algo diferente de 44

Não precisei fazer alterações no código

humblePilgrim
fonte
3

No meu caso, eu estava criando a célula programaticamente e continuava recebendo esse erro.

Eu estava adicionando os subviews e constrangimentos no UITableViewCell's initmétodo como este:

addSubview(rankingLabel)
addConstraints(cellConstraints)

Resolvi o problema adicionando-o ao celular contentView:

contentView.addSubview(rankingLabel)
contentView.addConstraints(cellConstraints)
gohnjanotis
fonte
1
Sempre adicione subvisões ao contentView, não ao UITableViewCelldiretamente.
dinesharjani
3

Defina a altura estimada da linha como zero e o aviso desaparecerá:

insira a descrição da imagem aqui

TruMan1
fonte
O problema real é uma restrição que falta em algum lugar. Você provavelmente está entrando em algo verticalmente em vez de definir top / restrições de fundo
TruMan1
1

Eu também experimentei esse aviso ao mudar para o Xcode 6 GM. Eu estava recebendo o aviso apenas quando girei o dispositivo de volta à sua posição original.

Estou usando UITableViewCells personalizado. A exibição da tabela do storyboard está definida para o meu tamanho personalizado (100,0 no meu caso). Embora as células da tabela sejam renderizadas corretamente como nas versões anteriores, não gostei da mensagem de aviso.

Além das idéias acima, adicionei este

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 100.0;
}

A tela é processada ... responde à rotação e não há mais mensagens de aviso.

DannyJi
fonte
Então, eu tentei usar seu método usando a linha que você me forneceu, mas ainda assim vi o mesmo erro. Também não uso rotação no meu aplicativo.
David E
1

No xcode 6.0.1, eu removi esses avisos especificando a altura da linha usando:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 44.0;
}
Fantini
fonte
1

Se você criou um tableViewCell personalizado para tableView, certifique-se de fornecer as restrições inferior e superior às células, também poderá receber essa mensagem se suas subvisões dentro das células personalizadas estiverem alinhadas no centro Y, que não exibiriam nenhuma mensagem de erro, mas causariam confusão com a identificação da altura da linha para a visualização da tabela, por sua vez, como na imagem que anexei, aqui temos as restrições superior e inferior

Ao criar uma célula personalizada para o tableView, você deve especificar a altura da linha ou as restrições superior e inferior para as subvisões da célula personalizada dentro da célula (por exemplo, etiqueta na célula personalizada, como na imagem abaixo)

Mas se isso não funcionar, tente definir a altura da linha do seu celular em vez de ser automático, como nesta imagem

Mas não se esqueça de desativar a marcação automática, você deve ajustar o tamanho da linha para alterações programaticamente que poderiam ter sido feitas automaticamente

poço do monstro
fonte
0

No storyboard, defina o cell Row heightcampo com o mesmo valor que Row heightem tableView(ambos com o mesmo valor funcionaram para mim).

Se você adicionar uma heightForRowAtIndexPathfunção ao seu código, isso poderá induzir um problema de desempenho, pois será chamado para cada célula. Portanto, tenha cuidado.

Daniel Gomez Rico
fonte
0

Você também poderá ver esta mensagem se suas únicas restrições estiverem definidas para alinhar todos os itens verticalmente e você não tiver / desejar uma altura especificada para a célula. Se você definir uma restrição superior / inferior no item, o aviso desaparecerá.

Micah Montoya
fonte
0

Eu tive esse problema quando meus rótulos e exibições no tableViewCell personalizado foram restritos ao customCell, não à sua Visualização de Conteúdo. Quando limpei as restrições e as conectei às células Content View, o problema foi resolvido.

Marija Zivkovic
fonte
0

Recebi a mesma mensagem de erro, verifique se todas as suas saídas são válidas, como restrições de exibição de tabela e visualização de tabela

Gulz
fonte
0

Se você estiver fazendo um cálculo dinâmico de altura,

  • você deve ter todos os elementos vinculados entre si em termos de restrições, como superior e inferior.
  • você definitivamente deve ter uma restrição inferior que está vinculada ao elemento na parte inferior da sua célula
S. Mert
fonte
0

Eu também tenho problema semelhante para célula tableview personalizado que tem altura de linha dinâmica. A altura dinâmica não foi refletida e recebeu o mesmo aviso no console. A solução é adicionar subvisões à célula em vez de contentView. BTW, eu criei subviews programaticamente.

Srinivas G
fonte
0

Eu tenho esse problema em TableViewCells, onde as restrições são definidas na inicialização, mas onde o conteúdo da célula é carregado posteriormente, isso significa que o mecanismo de reprodução automática não pode determinar a altura. As outras soluções aqui não funcionam porque eu preciso que a altura da célula seja UITableView.automaticDimension.

Acabei de adicionar uma restrição extra à célula:

contentView.heightAnchor.constraint(equalToConstant: 44, priority: .defaultLow)
Leon
fonte
0

Recebi este aviso hoje Tudo o que fiz foi apenas adicionar uma linha extra ao meu código

tableView.rowHeight = 200;

adicione esta linha de código dentro do

func tableView(_ tableView: UITableView, numberOfRowsInSection section:Int) -> Int {
  ...
}

e o código final se parece

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  tableView.rowHeight = 200;
  ...
}

esse código aumentará a altura da célula da linha da tabela para 200, a altura padrão é 44

SudhakarH
fonte
-1

Eu tenho o mesmo erro, devido a esta linha, esse erro foi mostrado.

self.layer.backgroundColor = UIColor (branco: 1, alfa: 0,2) as! CGColor

Acabei de alterar a linha da seguinte forma para corrigir o erro

self.layer.backgroundColor = UIColor (branco: 1, alfa: 0.2) .cgColor

Malik Hassnain
fonte