2015-01-16 6 views
8

Buona giornata, amici!iOS: set di vincoli a modifica di programma da Interface Builder

Non è stato possibile tentare di animare le viste impostate in IB dal codice. App blocca con seguente motivazione:

La gerarchia vista non è preparato per il vincolo ...

Ho visto alcune domande simili qui e il motivo era sempre che la vista che è stato creato a livello di codice, è non ancora aggiunto a superview. Ma ho creato tutte le viste in IB!

La console dice anche:

View non trovato in gerarchia del contenitore: (qui va è superview)

Non ha alcun senso per me perché in realtà si tratta di una sottoview della superview appropriata, e xcode lo sa: stampa subito la gerarchia delle viste e si adatta.

Quale potrebbe essere il motivo? Grazie!

Edit: il codice che uso:

- (void)setEditingConstraintsForView:(UIView *)view 
{ 
    // Pin given view to top, fix it height 
    NSDictionary *givenView = @{@"view":view}; 
    view.translatesAutoresizingMaskIntoConstraints = NO; 

    NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:nil views:givenView]; 
    NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view(height)]" options:0 metrics:@{@"height":@(viewHeight)} views:givenView]; 

    [self.animatedVIew addSubview:view]; 

    for (NSArray *constraints in @[horizontalConstraints, verticalConstraints]) { 
     [view addConstraints:constraints]; 
    } 
} 

Anche io eliminare tutti i vincoli che ho impostato in IB prima di installare nuovo:

- (NSDictionary *)constraintsFromIB 
{ 
    if (!_constraintsFromIB) { 
     _constraintsFromIB = @{@"view1":self.view1.referencingConstraintsInSuperviews, 
           @"view2":self.view2.referencingConstraintsInSuperviews, 
           @"view3":self.view3.referencingConstraintsInSuperviews }; 
    } 

    return _constraintsFromIB; 
} 

E poi:

- (void)updateViewConstraints 
{ 
    [super updateViewConstraints]; 

    // clear all constraints 
    for (NSString *viewName in self.constraintsFromIB.allKeys) { 
     for (NSLayoutConstraint *constraint in self.constraintsFromIB[viewName]) { 
      [constraint remove]; 
      } 

} }

UPDATE 2: metodo che uso invocare il cambiamento: quando l'utente tocca la vista, questo si chiama:

- (void)animateConstraintsForState:(LDYEditingLabel)state 
{ 
    self.editingLabel = state;   
    [UIView animateWithDuration:0.3 animations:^{ 
     [self updateViewConstraints]; 
     [self.view layoutIfNeeded]; 
    }]; 
} 

Più tardi nel updateViewConstraints: c'è un codice che fa scattare il mio metodo setEditingConstraintsForView:(UIView *)view

+0

Puoi mostrare un po 'di codice? – Paulw11

+0

Da quale metodo si richiama questo codice? 'ViewDidAppear'? 'ViewDidAppear'? o qualche altro metodo? – Paulw11

+0

Appena aggiunto un altro edit. Si innesca dal tocco sullo schermo utilizzando il blocco di animazione. –

risposta

22

se si utilizza IB per creare dei vincoli puoi aggiungere dei vincoli come uscita.

Quindi aggiornare il vincolo e chiamare [self updateViewConstraints]; nell'animazione bloccare

enter image description here

+0

Grazie per la risposta, che sicuramente funzionerebbe. Ma cosa succede se ho avuto un sacco di vincoli per adit? Ho bisogno che le viste appaiano e scompaiano, cambino posto sullo schermo e così via. Penso che se creo un punto vendita per ogni vincolo - l'implementazione del controller di visualizzazione sarebbe un pasticcio orribile –

+0

se stai usando il codice, non avresti il ​​ciclo del codice attraverso i vincoli di vista e cercheresti quello corretto? è molto più difficile da mantenere quando viene modificato il layout della vista. Questo potrebbe non essere il codice più pulito, ma dovrebbe essere abbastanza facile da mantenere e capire –

2

Se si trattasse di me, mi piacerebbe cablare le limitazioni per IBOutlets e solo modifico i vincoli esistenti. Probabilmente finirebbe per essere più facile che aggiungerli e rimuoverli a livello di codice.

Potrebbe anche essere necessario chiamare setNeedsLayout dopo aver modificato i vincoli.

+0

Grazie per il consiglio! Funziona perfettamente bene. Ma il motivo per cui ho provato a farlo a livello di programmazione è che ho molte viste per cambiare i vincoli. A un certo punto ho bisogno che tutte le viste scompaiano dallo schermo e ne mostro di nuove: datePicker, in particolare e diversi controlli personalizzati. E che dovrebbe tornare allo stato precedente. Cosa faresti in questo tipo di situazione? Grazie ancora! –

+0

Mantengo una serie di limiti di modifica quando si imposta la vista e poiché è possibile modificare la costante in ogni caso. I sottoclasse l'UIVIew e funziona bene per me. –

Problemi correlati