2016-02-17 19 views
7

Aggiungo uno UILabel (importo Etichetta) nello UIViewController nell'editor di storyboard. Quindi, nel file rapido, viewDidLoad, creo uno UITextField (paymentTextField) in modo programmatico e provo ad aggiungere un vincolo tra amountLabel e paymentTextField. Ecco il mio codice in viewDidload:Swift aggiungi il vincolo a livello di codice

let paymentTextField = UITextField() 
    paymentTextField.translatesAutoresizingMaskIntoConstraints = false 
    paymentTextField.frame = CGRectMake(15, 100, CGRectGetWidth(self.view.frame) - 30, 44) 
    self.view.addSubview(paymentTextField) 

    let bottonConstraint = NSLayoutConstraint(item: paymentTextField, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self.amountLabel , attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 30) 
    bottonConstraint.identifier = "paymentTextFieldSpacing" 
    NSLayoutConstraint.activateConstraints([bottonConstraint]) 

ma ottengo un errore:

"Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with items > and > because they have no common ancestor. Does the constraint reference items in different view hierarchies? That's illegal."

Qualcuno sa cosa è sbagliato? amountLabel viene trascinato direttamente nella vista nello storyboard e "paymentTextField" viene aggiunto programmaticamente alla stessa vista. Perché non hanno antenato comune?

risposta

4

L'errore indica che "perché non hanno un antenato comune", il che significa che non condividono lo stesso genitore. Per correlare il vincolo tra due elementi, devono avere una relazione figlio-genitore o una sorella.

Nel tuo caso assicurati che abbiano la stessa vista genitore prima di aggiungere il vincolo a livello di codice.

+1

Grazie per la risposta. Non riuscivo a capire come dare amountLabel e paymentTextField lo stesso genitore. Ho trascinato amountLabel nello storyboard e il suo genitore dovrebbe essere la vista esterna. Ho aggiunto paymentTextField a livello di codice a self.view e il suo genitore dovrebbe essere anche la vista esterna. Come mai hanno genitori diversi? – jimshicard

+1

Hai confermato che hanno lo stesso genitore, come stampare paymentTextField.superview? In caso contrario, trascina un IBOutlet dall'outlook dello storyboard al controller e utilizzalo per aggiungere paymentTextField come sottoview. Inoltre, assicurarsi di aggiungere il vincolo DOPO la chiamata ad addSubview, non prima. – Pauls

40

Mi sono imbattuto nello stesso problema che hai descritto in precedenza. Per rendere la sottoview programmatica, (nel tuo caso il paymentTextField) devi prima aggiungerla alla sottoview e poi applicare i tuoi vincoli.

Aggiungendo la vista secondaria per visualizzare prima, questo assicura che entrambe le viste abbiano lo stesso genitore.

Molto tardi, ma spero che questo aiuti qualcun altro.

+0

Posso verificarlo. È successo a me quando ho provato ad attivare i vincoli ma ho dimenticato di aggiungere i sottoview alla vista super. – christostsang

8

Lista di controllo per questo problema:

  • Controllare se si è aggiunto la visualizzazione a livello di codice creato al suo genitore prima che i vincoli che attivano
  • Controllare se si scrive vincoli codice di attivazione all'interno viewDidLoad()/viewWillAppear(). È necessario scrivere il codice di attivazione dei vincoli in updateViewConstraints o viewWillLayoutSubviews. (suggested by vmeyer)
  • Controllare se si spegne traslatoAutoresizingMaskIntoConstraints.
Problemi correlati