Incapaz de satisfazer simultaneamente as restrições, tentará se recuperar quebrando as restrições

145

Abaixo está a mensagem de erro que recebo na área de depuração. Ele funciona bem e nada está errado, exceto que eu recebo esse erro. Isso impediria a Apple de aceitar o aplicativo? Como faço para corrigir isso?

2012-07-26 01:58:18.621 Rolo[33597:11303] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x887d630 h=--& v=--& V:[UIButtonLabel:0x886ed80(19)]>",
    "<NSAutoresizingMaskLayoutConstraint:0x887d5f0 h=--& v=--& UIButtonLabel:0x886ed80.midY == + 37.5>",
    "<NSAutoresizingMaskLayoutConstraint:0x887b4b0 h=--& v=--& V:[UIButtonLabel:0x72bb9b0(19)]>",
    "<NSAutoresizingMaskLayoutConstraint:0x887b470 h=--& v=--& UIButtonLabel:0x72bb9b0.midY == - 0.5>",
    "<NSLayoutConstraint:0x72bf860 V:[UILabel:0x72bf7c0(17)]>",
    "<NSLayoutConstraint:0x72c2430 UILabel:0x72bfad0.top == UILabel:0x72bf7c0.top>",
    "<NSLayoutConstraint:0x72c2370 UILabel:0x72c0270.top == UILabel:0x72bfad0.top>",
    "<NSLayoutConstraint:0x72c22b0 V:[UILabel:0x72bf7c0]-(NSSpace(8))-[UIButton:0x886efe0]>",
    "<NSLayoutConstraint:0x72c15b0 V:[UILabel:0x72c0270]-(NSSpace(8))-[UIRoundedRectButton:0x72bbc10]>",
    "<NSLayoutConstraint:0x72c1570 UIRoundedRectButton:0x72bbc10.baseline == UIRoundedRectButton:0x7571170.baseline>",
    "<NSLayoutConstraint:0x72c21f0 UIRoundedRectButton:0x7571170.top == UIButton:0x886efe0.top>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x72bf860 V:[UILabel:0x72bf7c0(17)]>

Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
Johnny Cox
fonte
1
Este erro só vai acontecer no Xcode 4.5, para que você não pode enviá-lo para a App Store de qualquer maneira (até que seja liberado)
borrrden
Então não há nada errado então? E seria possível usar outra versão do xcode para poder enviar para a loja de aplicativos?
Johnny Cox
1
Sim, há algo errado, mas é irrelevante porque tem a ver com um recurso do iOS que ainda não está disponível nas versões públicas do Xcode. Se compilar com o 4.4, você poderá lançá-lo usando essa versão (foi lançada hoje).
borrrden
Recebo esta mensagem de erro para aplicativos OS X no Xcode 4.4. Eu não entendo isso
9788 Steve McLeod
@ Bartłomiej Semańczyk Você poderia, por acaso, entrar na sala: chat.stackoverflow.com/rooms/92522/autolayout-and-ios ? Desculpe, é aleatório, mas gostaria de receber seus conselhos sobre algo relacionado ao layout automático, obrigado!
cheznead

Respostas:

275

Eu recomendaria depurar e descobrir qual restrição é "a que você não deseja" . Suponha que você tenha o seguinte problema:

insira a descrição da imagem aqui

Sempre o problema é como encontrar as seguintes restrições e visualizações.

Existem duas soluções para fazer isso:

  1. HIERARQUIA DE VISUALIZAÇÃO DE DEPÓSITO (Não recomende isso)

Como você sabe onde encontrar restrições inesperadas (PBOUserWorkDayHeaderView), há uma maneira de fazer isso razoavelmente bem. Vamos encontrar UIViewe NSLayoutConstraintem retângulos vermelhos. Como conhecemos o ID deles na memória , é bastante fácil.

  • Pare o aplicativo usando a hierarquia de exibição de depuração :

insira a descrição da imagem aqui

  • Encontre o UIView adequado:

insira a descrição da imagem aqui

  • O próximo é encontrar o NSLayoutConstraint com o qual nos preocupamos:

insira a descrição da imagem aqui

Como você pode ver, os ponteiros de memória são os mesmos. Então, sabemos o que está acontecendo agora. Além disso, você pode encontrar NSLayoutConstraintna hierarquia de exibição. Como está selecionado em Exibir, também foi selecionado no Navegador.

insira a descrição da imagem aqui

Se você precisar, também pode imprimi-lo no console usando o ponteiro de endereço:

(lldb) po 0x17dce920
<UIView: 0x17dce920; frame = (10 30; 300 24.5); autoresize = RM+BM; layer = <CALayer: 0x17dce9b0>>

Você pode fazer o mesmo para cada restrição que o depurador apontará para você :-) Agora você decide o que fazer com isso.

  1. IMPRIMIR MELHOR (eu realmente recomendo dessa forma, é do Xcode 7)

    • defina um identificador exclusivo para cada restrição em sua exibição:

insira a descrição da imagem aqui

  • crie uma extensão simples para NSLayoutConstraint:

SWIFT :

extension NSLayoutConstraint {

    override public var description: String {
        let id = identifier ?? ""
        return "id: \(id), constant: \(constant)" //you may print whatever you want here
    }
}

OBJETIVO-C

@interface NSLayoutConstraint (Description)

@end

@implementation NSLayoutConstraint (Description)

-(NSString *)description {
    return [NSString stringWithFormat:@"id: %@, constant: %f", self.identifier, self.constant];
}

@end
  • construa-o novamente e agora você tem uma saída mais legível para você:

insira a descrição da imagem aqui

  • Depois de obter o seu, idbasta tocar no seu Find Navigator :

insira a descrição da imagem aqui

  • e encontre-o rapidamente:

insira a descrição da imagem aqui

COMO SIMPLES CORRIGIR ESSE CASO?

  • tentar mudar a prioridade para 999a restrição quebrado.
Bartłomiej Semańczyk
fonte
Isso apenas corrigiu meu bug ... muito obrigado. Como você faria isso para o objetivo c? Adicionar uma categoria?
cheznead
Thx para solução, mas posso usar a extensão no objetivo c?
dev.nikolaz
Esse identificador é o mesmo que accessibilityIdentifier que está disponível nos UIViews programaticamente. Caso contrário, como o identificador pode ser definido programaticamente?
Arunabh Das
@ Não, não é o mesmo. Leia esta resposta
Bartłomiej Semańczyk
3
I como o segundo caminho e eu acho que é a melhor maneira para rastrear restrição quebrado
Antarix
108

O problema que você está enfrentando é que o NSAutoresizingMaskLayoutConstraints não deve estar lá. Este é o antigo sistema de molas e suportes. Para se livrar dele, execute este método em cada exibição que você deseja restringir:

[view setTranslatesAutoresizingMaskIntoConstraints:NO];
David Wong
fonte
5
Quais são alguns dos motivos para uma exibição não aparecer ao definir setTranslatesAutoresizingMaskIntoConstraints como NO?
Topwik
1
como exemplo, eu crio um SSBadgeView (UIView), adiciono um subView de imageView ao SSBadgeView e, em seguida, adiciono o SSBAdgeView como subview ao UIReuseableView. Eu adiciono algumas restrições ao SSBadgeView e setTranslatesAutoresizingMaskIntoConstraints: NO no SSBadgeView. o subView de imagem do SSBadgeView é organizado conforme o esperado, mas o pai SSBadgeView da imagem não está em lugar algum.
topwik 26/06
1
Você esqueceu de desativar o TranslatesAutoresizingMaskIntoConstraints em suas sub-exibições
Softlion
É o que acontece quando eu defino essa propriedade, drive.google.com/file/d/0BxuYs8WHXCF7bV9ndHFrQ0dMYVE/… estou usando esta linha de código: [self.contentView setTranslatesAutoresizingMaskIntoConstraints: NO]; para (visualização UIView * em self.contentView.subviews) {[view setTranslatesAutoresizingMaskIntoConstraints: NO]; } No começo, costumava ser assim: drive.google.com/file/d/0BxuYs8WHXCF7OWlvZGQwN3FlbzQ/… Funcionou, devo dizer.
Rtwsthi
28

Cuidado , para não usar mais de uma restrição na mesma direção e tipo.

Por exemplo: Restrição vertical à direita = 15 e outra é> = 10.

Às vezes, o Xcode cria algumas restrições que você não percebe . Você precisa se livrar de restrições redundantes e o aviso de log certamente desaparecerá.

insira a descrição da imagem aqui

Além disso, você pode ler e detectar alguns motivos, diretamente do log :

NSLayoutConstraint: 0xa338390 V: | - (15) - [UILabel: 0xa331260] (Nomes: '|': UILabel: 0xa330270)>

Isso podemos ler como um problema na restrição UILabel, pois está levando a restrição vertical a 15pt de comprimento.

NSLayoutConstraint: 0x859ab20 H :-( 13) - | [UIView: 0x85a8fb0] ...

Isso seria uma restrição horizontal à direita, etc.

pedrouan
fonte
6

Eu tive várias dessas exceções lançadas, a maneira mais rápida e fácil de resolvê-las foi encontrar valores únicos nas exceções que eu procurei no código-fonte do storyboard. Isso me ajudou a encontrar as visualizações e restrições reais que causam o problema (eu uso userLabels significativos em todas as visualizações, o que facilita muito o rastreamento de restrições e visualizações) ...

Então, usando as exceções acima, eu abriria o storyboard como "código-fonte" no xcode (ou outro editor) e procuraria algo que eu pudesse encontrar ...

<NSLayoutConstraint:0x72bf860 V:[UILabel:0x72bf7c0(17)]> 

.. isso parece uma restrição vertical (V) em um UILabel com um valor de (17).

Examinando as exceções, também encontro

<NSLayoutConstraint:0x72c22b0 V:[UILabel:0x72bf7c0]-(NSSpace(8))-[UIButton:0x886efe0]>

Parece que o UILabel (0x72bf7c0) está próximo a um UIButton (0x886efe0) com algum espaçamento vertical (8) ..

Espero que seja o suficiente para eu encontrar as visões específicas no código-fonte do storyboard (provavelmente pesquisando o texto por "17" inicialmente), ou pelo menos alguns candidatos prováveis. A partir daí, eu devo ser capaz de descobrir quais visualizações estão no storyboard, o que facilitará muito a identificação do problema (procure por pinos "duplicados" ou pinos que conflitam com as restrições de tamanho).

C James
fonte
"Eu uso userLabels significativos" - o que são userLabels nesse contexto? (como definir)
Stripes
Na seção Documento do inspetor de identidade, há um campo "Etiqueta" .. que é traduzido para um valor "userLabel" no código-fonte do storyboard.
C James
Você também pode configurá-los clicando em uma visão selecionada na mão esquerda "Overview" painel (um pouco como renomear um arquivo no Finder)
C James
1
Provavelmente, a melhor coisa que li sobre como resolver o temido "Incapaz de satisfazer simultaneamente as restrições". dor. Descobri que o objeto mostrado neste momento "Tentará se recuperar quebrando a restrição <NSLayoutConstraint:" geralmente é o culpado e, como diz C James, provavelmente uma restrição de altura ou largura que entra em conflito com as restrições de fixação. Achei difícil remover a altura, mas, como as restrições estavam corretas, a altura pôde ser recolhida das outras restrições. A adição de uma restrição de altura confundiu o Layout automático, e é isso que procuro agora.
latenitecoder
6

Eu tive dificuldade em descobrir quais restrições estavam causando esse erro. Aqui está uma maneira mais simples de fazer isso.

Estou usando o Xcode 6.1.1

  1. "Command + A" para selecionar todos os UILabels, UIImages etc.
  2. Clique em Editor -> Fixar> (Selecionar ...) para Superview
  3. clique novamente em Editor -> Resolver problemas de layout automático -> Adicionar restrições ausentes ou Redefinir para restrições sugeridas. Depende do seu caso.
Ronaldoh1
fonte
5

Eu tive esse problema porque meus .xibarquivos estavam usando o layout automático.

No inspetor de arquivos, primeira guia. Desmarcar "Usar Autolayout" resolveu o problema.

inspetor de arquivos de execução automática

Stéphane Bruckert
fonte
Fiz isso e resolvi o problema, mas um 'UIImageView' que eu tinha na parte superior da tela (que eu usei como barra de navegação) foi movido para a parte inferior da tela. Você sabe por que isso aconteceu?
Dietbacon
1
A execução automática usa restrições para controlar o layout dos objetos. Como você acabou de desativar o pagamento automático, essas restrições provavelmente desapareceram e, portanto, a posição do seu UIImageViewmudou. Você deve definir essa posição novamente, programaticamente ou através do Interface Builder.
Stéphane Bruckert
5

Aqui está a minha experiência e solução. Não toquei no código

  1. Selecionar visualização (UILabel, UIImage etc.)
  2. Editor> Fixar> (Selecionar ...) na Superview
  3. Editor> Resolver problemas de layout automático> Adicionar restrições ausentes
royemi
fonte
4

use rapidamente este código

view.translatesAutoresizingMaskIntoConstraints = false
Arun Kumar P
fonte
1
Essa é uma resposta rápida para uma pergunta marcada com objetivo-c.
22416 Tobi Nary
2
De qualquer forma, eu mencionei que esse é um código rápido. e é trabalhado para mim. rápido / objetivo é ter SDK de toque de cacau comum.
Arun Kumar P
2

Eu segui perguntas e respostas SO de cada consulta de pesquisa. Mas todos eles estão relacionados com um específico.

No básico, quero dizer, antes de você escrever um formato (pode ser um formato simples), ele fornece avisos.

No iOS 8.0, as visualizações padrão são classes de tamanho. Mesmo se você desabilitar as classes de tamanho, elas ainda conterão algumas restrições de layout automático.

Portanto, se você planeja definir restrições via código usando VFL. Então você deve cuidar de uma linha abaixo.

// Remove constraints if any.
[self.view removeConstraints:self.view.constraints];

Eu pesquisei bastante no SO, mas a solução estava no Apple Sample Code .

Portanto, você deve remover as restrições padrão antes de planejar adicionar uma nova.

Kampai
fonte
1

Para mim, a principal razão desse problema foi que eu esqueci de desmarcar AutoLayoutno Xibeditor. De fato, fiz muitos ajustes XIBno código.

Giuseppe
fonte
1
 for(UIView *view in [self.view subviews]) {
    [view setTranslatesAutoresizingMaskIntoConstraints:NO];
}

Isso me ajudou a entender o ponto de vista que estava causando o problema.

Grant Carlisle
fonte
1

Nenhuma das respostas anteriores é útil na minha situação. Estou executando o XCode 10.1 e testando meu aplicativo no simulador para um "iPad (5ª geração)". O simulador está executando o iOS 12.1.

Eu tenho uma visão raiz simples no meu storyboard, com duas subviews UITextField. Não há nenhuma restrição sendo usada no storyboard. E não tenho objetos UIButtonBarView no aplicativo ou no storyboard.

Nenhuma mensagem é impressa quando o aplicativo é iniciado e expõe a visualização raiz. Nenhuma quando o dispositivo simulado é girado.

Mas no simulador, no momento em que clico em um dos campos de texto, a extensão do teclado surge na parte inferior da tela, embora não seja o teclado completo, que nunca parece aparecer no simulador. Mas o seguinte está impresso no terminal:

Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it. 
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
"<NSAutoresizingMaskLayoutConstraint:0x6000034e7700 h=--& v=--& UIKeyboardAssistantBar:0x7f9c7d714af0.height == 0   (active)>",
"<NSLayoutConstraint:0x6000034aba20 V:|-(0)-[_UIUCBKBSelectionBackground:0x7f9c7d51ec70]   (active, names: '|':_UIButtonBarButton:0x7f9c7d51de40 )>",
"<NSLayoutConstraint:0x6000034aba70 _UIUCBKBSelectionBackground:0x7f9c7d51ec70.bottom == _UIButtonBarButton:0x7f9c7d51de40.bottom   (active)>",
"<NSLayoutConstraint:0x6000034fb3e0 V:|-(0)-[_UIButtonBarStackView:0x7f9c7d715880]   (active, names: '|':UIKeyboardAssistantBar:0x7f9c7d714af0 )>",
"<NSLayoutConstraint:0x6000034fb750 V:[_UIButtonBarStackView:0x7f9c7d715880]-(0)-|   (active, names: '|':UIKeyboardAssistantBar:0x7f9c7d714af0 )>",
"<NSLayoutConstraint:0x6000034abc00 'UIButtonBar.maximumAlignmentSize' _UIButtonBarButton:0x7f9c7d51de40.height == UILayoutGuide:0x600002ef4e00'UIViewLayoutMarginsGuide'.height   (active)>",
"<NSLayoutConstraint:0x6000034d7cf0 'UIView-bottomMargin-guide-constraint' V:[UILayoutGuide:0x600002ef4e00'UIViewLayoutMarginsGuide']-(9)-|   (active, names: '|':_UIButtonBarStackView:0x7f9c7d715880 )>",
"<NSLayoutConstraint:0x6000034d7c50 'UIView-topMargin-guide-constraint' V:|-(10)-[UILayoutGuide:0x600002ef4e00'UIViewLayoutMarginsGuide']   (active, names: '|':_UIButtonBarStackView:0x7f9c7d715880 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000034aba70 _UIUCBKBSelectionBackground:0x7f9c7d51ec70.bottom == _UIButtonBarButton:0x7f9c7d51de40.bottom   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

Certamente parece-me que tudo isso tem a ver com nada no meu aplicativo e tudo a ver com a maneira como a Apple está criando sua própria exibição de teclado, mesmo com minha pequena extensão declarada combinada com ela.

Portanto, a questão permanece: existe algo que eu, como desenvolvedor de aplicativos, sou responsável por fazer (na suposição de que isso seja um monte de coisas que vale a pena prestar atenção) ou é apenas o problema / bug da Apple?

FWIW, essa mensagem de problema de restrição não ocorre ao simular um modelo mais recente do iPad, como o iPad Pro de 12,9 polegadas (3ª geração). Mas a mensagem aparece ao simular um iPad Pro de 9,7 polegadas ". Todos alegando que estão executando o iOS 12.1.

jsbox
fonte
1

Estou recebendo o mesmo erro, mas apenas em uma exibição específica, quando toco no primeiro campo de texto e depois no próximo campo de texto.

Estou escrevendo no SwiftUI para iOS 13.4

 Unable to simultaneously satisfy constraints.
        Probably at least one of the constraints in the following list is one you don't want. 
        Try this: 
            (1) look at each constraint and try to figure out which you don't expect; 
            (2) find the code that added the unwanted constraint or constraints and fix it. 
    (
        "<NSLayoutConstraint:0x2809b6760 'assistantHeight' TUISystemInputAssistantView:0x105710da0.height == 44   (active)>",
        "<NSLayoutConstraint:0x2809ccff0 'assistantView.bottom' TUISystemInputAssistantView:0x105710da0.bottom == _UIKBCompatInputView:0x10525ae10.top   (active)>",
        "<NSLayoutConstraint:0x2809cccd0 'assistantView.top' V:|-(0)-[TUISystemInputAssistantView:0x105710da0]   (active, names: '|':UIInputSetHostView:0x105215010 )>",
        "<NSLayoutConstraint:0x2809ca300 'inputView.top' V:|-(0)-[_UIKBCompatInputView:0x10525ae10]   (active, names: '|':UIInputSetHostView:0x105215010 )>"
    )

    Will attempt to recover by breaking constraint 
    <NSLayoutConstraint:0x2809ccff0 'assistantView.bottom' TUISystemInputAssistantView:0x105710da0.bottom == _UIKBCompatInputView:0x10525ae10.top   (active)>

    Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
    The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
DckBrd
fonte
0

Eu também estava recebendo o mesmo problema de quebrar restrições no log, para um viewCircle no xib. Eu quase tentei tudo listado acima e nada estava funcionando para mim. Tentei alterar a prioridade da restrição de altura que estava quebrando no log (confirmada adicionando um identificador para as restrições no xib) e insira a descrição da imagem aqui

Mughal
fonte
-1

Uma coisa a ser observada (pelo menos isso me tropeçou) era que eu estava removendo a restrição da visão errada. A restrição que eu estava tentando remover não era uma restrição infantil da minha opinião, então, quando o fiz

myView.removeConstraint(theConstraint)

na verdade, não estava removendo nada, porque eu precisava ligar

myView.superView.removeConstraint(theConstraint)

uma vez que a restrição era tecnicamente uma restrição irmão da minha opinião.

Adam Johns
fonte
-4

veloz 4

Acabei de adicionar esta linha no viewDidLoad e funcionou bem comigo.

view.removeConstraints(view.constraints)
Faris
fonte