2013-02-12 37 views
19

terminazione app a causa di eccezione non identificata 'NSGenericException'NSGenericException 'la ragione:' Impossibile installare vincolo vista

terminazione app a causa di eccezione non identificata 'NSGenericException', la ragione: 'Impossibile installare vincolo vista. Il vincolo fa riferimento a qualcosa di esterno al sottostruttura della vista? Questo è illegale. vincolo: view :; layer =; contentOffset: {0, 0}> '

+0

inserire il codice qui per maggiori undersatnding – iPatel

+0

in cui versione del sistema operativo che si stanno ottenendo questo errore –

+0

ho il sospetto è necessario approfondire la tua domanda, e/o pubblicare il tuo codice per ottenere risposte più utili. – ipmcc

risposta

32

È necessario installare il vincolo sul "superiore" delle due viste. Un buon modo per fare questo genere è come questo:

NSLayoutConstraint* constraint = ...; 
NSView* firstView = constraint.firstItem; 
NSView* secondView = constraint.secondItem;  
[[firstView ancestorSharedWithView: secondView] addConstraint: constraint]; 

Solo una parola di cautela: E 'bene ricordare qui che gli attributi vincoli vengono valutati nel contesto della vista su cui sono aggiunti. Ad esempio, il valore di NSLayoutAttributeLeft della viewA, per un vincolo installato sulla viewB, viene interpretato nello spazio delle coordinate della viewB. Per i vincoli che fanno riferimento solo alle viste di pari livello o alla loro superview, questo fatto è in gran parte irrilevante, ma non vi è alcuna restrizione che i vincoli non possano fare riferimento a due viste che non sono fratelli o genitori diretti.

+0

nella mia app utilizzo il selettore di date e dopo la data selezionata navigo alla vista successiva e quando ritorna a questo controller vista l'app è in crash e l'errore sopra è generato ...... – adevani11

+0

è questo 'ancestorSharedWithView' solo definito per mac e non iOS? Vedo che è definito nella libreria AppKit.framework che appartiene solo a mac OSX10.8 – abbood

+0

Huh. In effetti non sembra essere un equivalente su UIView, il che sembra un po 'sciocco. Sarebbe abbastanza semplice scrivere un tale metodo: basta salire sulla gerarchia di firstView e chiedere ad ogni passo '[secondView isDescendantOfView: x]'. Ma il concetto è lo stesso: si desidera sempre installare un vincolo su un antenato comune di tutte le viste coinvolte e il vincolo verrà risolto nello spazio delle coordinate della vista su cui è stato installato. – ipmcc

3

Ho riscontrato questo errore su iOS6. Nel mio caso è stato perché ho iniziato a rimuovere le sottoview senza prima rimuovere i vincoli.

// I had forgotten to remove constraints first. This caused the crash. 
[self.view removeConstraints:self.view.constraints]; 

NSArray *subviews = self.view.subviews; 
for (UIView *subview in subviews) { 
    [subview removeFromSuperview]; 
} 

[self addYourSubviewsHere]; 
+0

Il problema con questo codice è che rimuoverà TUTTI i vincoli per self.view e non solo i vincoli relativi alla sottoview che stai rimuovendo ... – nduplessis

10

Simile a neoneye stavo ottenendo questo a causa della rimozione di subview con vincoli. Tuttavia ho avuto un vincolo che è stato il posizionamento vista primaria, e questo veniva rimosso se ho chiamato [self.view removeConstraints:self.view.constraints]; Invece ho fatto questo cambiamento,

Codice originale:

for (UIView *subview in [view subviews]) { 
    [subview removeFromSuperview]; 
} 

fisso per rimuovere vincoli subviews:

NSMutableArray * constraints_to_remove = [ @[] mutableCopy] ; 
for(NSLayoutConstraint * constraint in view.constraints) { 
    if([view.subviews containsObject:constraint.firstItem] || 
     [view.subviews containsObject:constraint.secondItem]) { 
     [constraints_to_remove addObject:constraint]; 
    } 
} 
[view removeConstraints:constraints_to_remove]; 

for (UIView *subview in [view subviews]) { 
    [subview removeFromSuperview]; 
} 

UPDATE: Così mi ha colpito questo errore di nuovo - ed è stato a causa di rimozione di una singola vista questa volta. Aggiunta una funzione per rimuovere la vista in modo pulito:

void cleanRemoveFromSuperview(UIView * view) { 
    if(!view || !view.superview) return; 

    //First remove any constraints on the superview 
    NSMutableArray * constraints_to_remove = [NSMutableArray new]; 
    UIView * superview = view.superview; 

    for(NSLayoutConstraint * constraint in superview.constraints) { 
    if(constraint.firstItem == view ||constraint.secondItem == view) { 
     [constraints_to_remove addObject:constraint]; 
    } 
    } 
    [superview removeConstraints:constraints_to_remove]; 

    //Then remove the view itself. 
    [view removeFromSuperview]; 
} 
0

ho trovato l'aggiunta di questa una linea di codice risolto questo problema per uno ScrollView cacao.

[scrollView setTranslatesAutoresizingMaskIntoConstraints:NO]; 

penso che certe vedute aggiungere vincoli in fase di esecuzione in conflitto, pertanto quando si aggiunge il proprio via Objective C, quindi è necessario disattivare questo comportamento ...

2

ho avuto questo problema utilizzando un UIPickerView come ingresso di un UITextField (usando l'Autolayout). Quando spingo un altro viewController e quindi lo apro alla viewController con il selettore, l'app si blocca. Ho trovato la seguente soluzione, nella UIPickerViewController:

-(void)viewWillAppear:(BOOL)animated{ 

    [self.pickerView removeFromSuperview]; 
    [self.pickerView setTranslateAutoresizingMaskIntoContraints:YES]; 
    [self.view addSubview]; 

} 

È anche possibile impostare l'UIPickerViewPosition dopo la rimozione da superview. Spero che possa aiutarti!

+0

Ho lo stesso problema che uso 'UIDatePicker' come' TextField' 'inputAccessoryView'. Spingo un controller della vista e torno indietro e lancia un'eccezione. Ho provato il tuo codice ma non funziona per me. Si noti che ho 'UIDatePicker' nello storyboard (non creando attraverso il codice). – Geek

+0

dal modo in cui questo problema è un bug iOS7 e penso che sarà risolto sulla versione 7.1. iOS mostra molti problemi in molte cose che si riferiscono al caricamento automatico. Sto anche usando il pickerview nello storyboard, e per me funziona. Puoi provare a rimuovere il datepicker da superview prima di lasciare viewController. Oppure puoi provare a utilizzare questo codice su viewDidAppear o viewDidLayoutSubviews. Spero che possa aiutarti! Grazie per la segnalazione. –

0

stesso errore, soluzione diversa qui:

ho ottenuto questo errore all'avvio di mio app su iOS 6 dopo l'aggiunta di una nuova visione e dimenticando di spegnere Use Auto Layout su di essa nel costruttore di interfaccia ... lo odio non esiste un'impostazione standard per NON NON utilizzare il layout automatico per le nuove viste ...