Usando o XCode 4.5 e iOS 6, estou desenvolvendo um aplicativo com uma visualização de tabela simples com células personalizadas. Já fiz isso centenas de vezes no iOS 5 e inferior, mas por algum motivo o novo sistema autoLayout está me dando muitos problemas.
Eu configurei minha visualização de tabela e célula de protótipo em IB, adicionei subvisualizações e conectei-as como IBOutlets, em seguida, configurei meu delegado e fonte de dados. No entanto, agora, sempre que a primeira célula é buscada cellForRowAtIndexPath
, recebo o seguinte erro:
*** Falha de declaração em - [ShopCell layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2372/UIView.m:5776
*** Encerrando o aplicativo devido à exceção não detectada 'NSInternalInconsistencyException', motivo: 'Layout automático ainda necessário após a execução de -layoutSubviews. A implementação de -layoutSubviews da ShopCell precisa chamar super. '
Não implementei um método -layoutSubviews em minha célula com subclasse (ShopCell) e, mesmo quando tento fazer isso e adicionar a super chamada, como sugere, ainda recebo o mesmo erro. Se eu remover as subvisualizações da célula em IB e alterá-las para um UITableViewCell padrão, tudo funcionará conforme o esperado, embora, é claro, fique sem dados em minhas células.
Tenho quase certeza de que está faltando algo simples, mas não consigo encontrar nenhuma documentação ou guia que sugira o que fiz de errado. Qualquer ajuda seria apreciada.
Edit: Apenas tentei alterá-lo para um UITableViewCell em IB e deixar todas as subvisualizações no lugar, ainda o mesmo erro.
fonte
lldb [[UIWindow keyWindow] _autoLayoutTrace]
na área do depurador se o layout automático for usado.Respostas:
Eu encontrei o mesmo problema ao adicionar manualmente restrições no código. No código, eu estava fazendo o seguinte:
Hipótese
Pelo que posso dizer, o problema é que, quando você desativa
translatesAutoresizingMaskIntoConstraints
, UITableViewCell começa a usar o Auto Layout e falha naturalmente porque a implementação subjacente delayoutSublayersForLayer
não chama super. Alguém com Hopper ou alguma outra ferramenta pode confirmar isso. Já que você está usando IB, você provavelmente está se perguntando por que isso é um problema ... e isso porque usar IB desativa automaticamente astranslatesAutoresizingMaskIntoConstraints
visualizações às quais adiciona restrições (adicionará automaticamente uma restrição de largura e altura em seu lugar).Solução
Minha solução foi mover tudo para o
contentView
.Não tenho 100% de certeza se isso vai funcionar no Interface Builder, mas se você empurrar tudo para fora de sua célula (supondo que você tenha algo diretamente nele), então deve funcionar. Espero que isso ajude você!
fonte
subview.translatesAutoresizingMaskIntoConstraints = NO'
cada subvisualização que estava adicionando ao contentView.self.contentView.translatesAutoresizingMaskIntoConstraints = NO
para oUITableViewCell
.Aparentemente, a implementação de layoutSubviews de UITableViewCell não chama super, o que é um problema com o layout automático. Eu estaria interessado em ver se colocar a categoria abaixo em projetos corrige as coisas. Ajudou em um projeto de teste.
Posso adicionar o problema que apareceu para mim ao usar um backgroundView na célula da tabela, pois isso é adicionado como uma subvisualização à célula (enquanto a maioria das subvisualizações deve ser adicionada ao contentView da célula da tabela, que geralmente deve funcionar melhor).
Observação: parece que esse bug foi corrigido no iOS7; Consegui remover este código, ou pelo menos adicionar uma verificação de tempo de execução para que seja feito apenas se estiver executando no iOS6.
fonte
UITableView
pelo mesmo motivo (iOS 6.1 b1)Eu tive o mesmo bug por alguns meses. Mas descobri qual era o problema.
Quando eu crio um arquivo IB, um
UIView
já é adicionado. Se você usar esta visualização, o aplicativo não trava quando o layout automático é desabilitado (mas há outros problemas). Quando você usar o layout automático, você tem que selecionar a direita vista na biblioteca de objetos:UITableViewCell
.Na verdade, você deve sempre usar este item porque todas as subvisualizações são adicionadas ao
contentView
deUITableViewCell
.Isso é tudo. Tudo vai ficar bem.
fonte
Eu tive o mesmo problema com custom
UITableViewHeaderFooterView
+ xib.Vi algumas respostas aqui, mas descobri que implementação
-layoutSubviews
em minha classe de visualização de rodapé personalizada corrige o problema:fonte
Eu estava vendo isso como resultado da modificação de restrições em minha implementação de layoutSubviews. Mover a chamada para super do início ao fim do método corrigiu o problema.
fonte
Tive o mesmo problema no iOS 7 (o iOS 8 parece corrigir). A solução para mim foi chamar
[self.view layoutIfNeeded]
no final do meuviewDidLayoutSubviews
método.fonte
Eu tive o mesmo problema. O problema estava na forma como estava criando a célula Xib. Eu criei um Xib normalmente e apenas alterei o tipo do "UIView" padrão para minha classe UITableViewCell personalizada. A maneira correta de fazer isso é primeiro excluir a visualização padrão e, em seguida, arrastar o objeto de célula da visualização de tabela para o xib. Mais detalhes aqui: http://allplayers.github.io/blog/2012/11/18/Custom-UITableViewCell-With-NIB/
fonte
Resolvi o problema desativando o "Autolayout" para todas as subvisualizações de minha célula de exibição de tabela personalizada.
No xib de uma célula personalizada, selecione uma subvisualização e desmarque File Inspector> Interface Builder Document> Use Autolayout
fonte
Tive um problema semelhante, não
UITableViewCell
emUITableView
si, mas em si mesmo. Por ser o primeiro resultado no Google vou postar aqui. Acontece que esseviewForHeaderInSection
era o problema. Criei umUITableViewHeaderFooterView
e configureitranslatesAutoresizingMaskIntoConstraints
paraNO
. Agora vem a parte interessante:iOS 7:
Se eu fizer isso, o aplicativo trava com
OK, pensei que você não pode usar o layout automático em um cabeçalho de exibição de tabela e apenas nas subvisualizações. Mas essa não é toda a verdade como você verá mais tarde. Para resumir: Não desative a máscara de redimensionamento automático para o cabeçalho no iOS 7. Caso contrário, está funcionando bem.
iOS 8:
Se eu não usasse isso, obteria o seguinte resultado:
Para iOS 8, você deve desativar a máscara de redimensionamento automático para o cabeçalho.
Não sei por que ele se comporta dessa forma, mas parece que a Apple corrigiu algumas coisas no iOS 8 e o layout automático está funcionando de forma diferente no iOS 7 e iOS 8.
fonte
Como alguém acima já afirmou, quando você cria uma visualização para uso em um UITableView, você deve excluir a visualização criada por padrão e arrastar um UITableViewCell ou UITableViewHeaderFooterView como a visualização raiz. No entanto, existe uma maneira de consertar o XIB caso você tenha perdido essa parte. Você tem que abrir o arquivo XIB em um editor de texto e na tag raiz e seu filho direto adicionar / alterar o atributo
translatesAutoresizingMaskIntoConstraints
paraYES
, por exemplo<view contentMode="scaleToFill" horizontalHuggingPriority="1000" id="1" translatesAutoresizingMaskIntoConstraints="YES" customClass="MXWCollapsibleTableHeaderView">
fonte
Estou encontrando isso e parece que está relacionado às subclasses UITableViewCell como células de protótipo que têm especificamente outras subclasses UIView personalizadas adicionadas a elas. Enfatizo o 'custom' aqui porque tive sucesso com células que têm apenas filhos UIKit, mas ele falha ao tentar construir as restrições para visualizações que criei sob medida, gerando o erro declarado na pergunta do autor.
Tive que separar minhas células em pontas independentes que não usam AutoLayout.
Vamos esperar que a Apple limpe essa bagunça.
fonte
Adicione suas subvisualizações ao contentView da célula em vez da própria célula. Então, em vez de:
[self addSubview:someView];
você deve usar
[self.contentView addSubview:someView];
fonte
Eu encontrei este porque eu tinha adicionado inicialmente um UIView em vez de um UITableViewCell a um arquivo xib.
fonte
Eliminei esse erro desacoplando o
backgroundView
conector de meu plano de fundoUIImageView
e oaccessoryView
conector de minhasUIButton
personalizações. Suspeito que eles não deveriam ser usados da maneira como eu os estava usando.fonte
Eu tive esse problema pela primeira vez hoje. Até agora, tive várias experiências no uso de subclasses de protótipo UITableViewCell, mas nunca tive esse problema. O que era diferente na célula com a qual estava trabalhando era que eu tinha um IBOutlet para o -backgroundView que estava usando para colorir a célula. Descobri que, se criasse uma nova propriedade e ainda adicionasse um novo UIView que se estendesse por toda a célula, essa afirmação desapareceria. Para verificar se essa era a causa, voltei a anexar essa visualização ao outlet backgroundView e a declaração reapareceu. Até agora, nenhum outro problema com o uso do AutoLayout em um protótipo de subclasse UITableViewCell desde que fiz essa alteração.
fonte
Não obtive uma solução adequada para esse problema, mas você pode corrigi-lo usando frames e não definindo a propriedade translatesAutoresizingMaskIntoConstraints como No (por padrão é sim, então não defina)
fonte
Eu tenho experimentado a mesma coisa. Descobriu-se que, se você adicionar programaticamente uma subvisualização de seu ShopCell .xib / storyboard, que usa o layout automático, como uma subvisualização para outra visão, essa exceção pode ser lançada, dependendo de como suas restrições estão configuradas. Meu palpite é que as restrições criadas no IB são o que cria os problemas ao adicionar programaticamente uma visualização como uma subvisão, uma vez que mantém as restrições de viewA -> viewB, enquanto isso você pode adicionar viewB como uma subvisão de viewC. Você entendeu (essa frase até me confunde)?
Na minha situação - visto que foram as visualizações muito simples que causaram o problema - criei as visualizações programaticamente e não no IB. Isso resolveu tudo. Você pode extrair essas visualizações para outros arquivos xib e desativar o layout automático para eles. Eu acho que funcionaria.
fonte
Em algumas situações, isso resolve o problema de layout facilmente (dependendo do seu layout). Dentro de sua subclasse UITableView, em awakeFromNib ou init, defina a máscara de redimensionamento automático:
Por padrão, é definido como UIViewAutoresizingNone
fonte
[tableViewCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height
para obter a altura, que uso emheightForRowAtIndexPath
.No meu caso,
O UIImageView referenciado para o layout automático para UITableView é atribuído a backgroundView do UITableView.
Portanto, removi UIImageView para backgroundView do UIView (visualização Root) e redefina (remova) todas as referências de layout automático para esse UIImageView. Coloquei esse UIImageView para plano de fundo do lado de fora do UIView (visualização raiz). E então atribua ao backgroundView do UITableView no código.
Em seguida, corrigido.
fonte
Eu encontrei a solução.
No meu caso, criei a visualização da célula em storyboard (com layout automático habilitado) e defini a interface UITableViewCell customizada em meu ViewController.m, tenho que mover a interface para ViewController.h.
fonte
Eu encontrei o mesmo problema quando uso o storyboard para criar o UITableViewCell personalizado. Felizmente encontrei o problema, porque eu coloquei o acessórioView ([UITableViewCell setAccessoryView:]) no UIButton que adicionei à célula.
Solução
Proposta
fonte
Esse problema pode ser causado pelo esquecimento de ligar para
[super viewDidAppear:]
dentroviewDidAppear
, mas tenho certeza de que não é a única causa.fonte
Eu tive exatamente o mesmo problema. Aqui está o problema com meu projeto:
Quando trabalhei no Interface Builder para criar um UITableViewCell personalizado, arrastei uma Visualização em vez de uma Célula de Visualização de Tabela do painel de coleção de objetos no Xcode
como a célula de tabela personalizada.
Se você estiver na mesma situação, aqui está a solução:
Exclua a visualização no construtor de interface, certifique-se de arrastar uma Célula de Visualização de Tabela do painel de coleção de objetos e refazer a visualização de célula da tabela customizada. Você pode copiar os objetos da visualização antiga e colá-los na tela para a nova Célula de Visualização de Tabela.
fonte
Tive um problema muito semelhante com a visualização do rodapé da tabela que estava configurando no Xcode 6, iOS 7 ou 7. A solução estava no formato do arquivo nib. Aparentemente, ele estava preso no formato Xcode 4 ou algo assim. Alterar as configurações do arquivo para "abre em: Xcode 6.0" (ou Padrão, nesse caso), corrigiu instantaneamente. Achei a solução por acaso: estava me deixando louco, então apaguei o arquivo inteiro e criei novamente, obviamente com as configurações padrão. Não tenho ideia de por que simplesmente editar o arquivo no Xcode mais recente não o converteu em um formato Xcode 5+, como geralmente acontece.
fonte
Eu fui teve o mesmo problema. Eu fui para o meu DetailViewController e renomeei o identificador para UIView. Ele estava anteriormente em UITableView. Isso resolveu o problema. Este problema não precisa estar em seu DetailViewController. Pode ser em qualquer outro. Tente renomeá-lo para o identificador respeitado.
fonte
Eu tive um problema semelhante com células de visualização de tabela estática no IB. Uma das células tinha uma subvisualização que tinha uma classe que foi alterada por engano para uma subclasse de UITextfield. O compilador não deu nenhum aviso / erro. Mas, em tempo de execução, o sistema não conseguiu carregar o controlador de visualização com a falha mencionada como resultado.
fonte
O problema é o sequenciamento das chamadas de layout para as subvisualizações:
Verificação de saída
Aparece no iOS <8
fonte
Solução: altere as restrições antes de chamar super layoutSubviews
fonte
Eu modifiquei a resposta de Carl Lindberg para substituir em
UITableView
vez disso e começou a funcionar para mim:UITableView + AutoLayoutFix.h
UITableView + AutoLayoutFix.m
Então
MyViewController.m
, acabei de importar a categoria:fonte
Eu encontrei o mesmo problema e finalmente descobri que o motivo era que adicionei uma restrição ao UITableViewCell, que deveria ser o contentView do UITableViewCell . Quando mudei a restrição, tudo correu bem!
fonte