2012-11-20 5 views
12

Ho creato una sottoclasse di UIView per creare un groupView personalizzato che uso per aggiungere alcune cose al mio layout in modo semplice. Questo groupView include un UILabel che viene usato come titolo e un UIView che disegna un roundRect sul suo CALayer con un colore di sfondo. Pensa alle sezioni di UITableView. Aggiungo questo groupView allo storyboard facendo cadere un UIView e cambiando la sua classe nella mia sottoclasse. Funziona tutto bene, ho impostato l'intestazione tramite gli attributi di runtime definiti dall'utente in Xcode. Tutto funziona alla grande, aggiungo UILabels a questa vista sullo storyboard e crea l'etichetta di titolo e roundrect quando viene eseguito.Autolayout a livello di programmazione su una sottoview di una UIView sottoclasse

struttura del mio GroupView:

  1. GroupView: (UIView) ClipToBounds: NO;
    • intestazione: (UILabel) posizionato sopra il groupView.
    • contentView: (UIView) crea il roundRect e il colore tramite CALayer, deve avere le stesse dimensioni del groupView.

Allora qual è il problema? Beh, trattare con l'autolayout è un problema, ma per far funzionare questa sottoclasse di UIView ho bisogno di impostare i vincoli contentView a livello di programmazione. Non riesco a capire la sintassi di questa stringa di formato ASCII di layout automatico. Attualmente ho:

_contentView = [[UIView alloc]initWithFrame:self.bounds]; 

    _contentView.layer.cornerRadius = 5.0f; 
    _contentView.layer.masksToBounds=YES; 
    _contentView.backgroundColor=_backgroundColor; 
    _contentView.layer.borderWidth=_borderWidth; 
    _contentView.layer.borderColor=_borderColor.CGColor; 
    [self insertSubview:_contentView atIndex:0]; 
    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(self,_contentView); 
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"[self]-0-[_contentView]-0-[self]" options:0 metrics:nil views:viewsDictionary]; 

    for (NSLayoutConstraint *constraint in constraints) { 
     [_contentView addConstraint:constraint]; 
    } 

che va in crash con: * di terminazione app a causa di eccezione non identificata 'NSGenericException', la ragione: 'Impossibile installare vincolo vista. Il vincolo fa riferimento a qualcosa al di fuori del sottostruttura della vista? Questo è illegale. vincolo: view:> '

ho provato questa prima e ancora non ha funzionato:

NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_contentView); 
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-0-[_contentView]-0-|" options:0 metrics:nil views:viewsDictionary]; 

che va in crash con: * terminazione app a causa di eccezione non identificata 'NSGenericException', la ragione:' Impossibile installare il vincolo sulla vista. Il vincolo fa riferimento a qualcosa al di fuori del sottostruttura della vista? Questo è illegale. vincolo: view:>'

RANT: In qualche modo questo layout automatico è supponiamo di salvarci lavoro, ma io non vedo come i benefici fuori di peso l'overhead in questo momento. Perché sulla Terra si sono spostati dall'utilizzo di riferimenti e metodi o addirittura digitare defs a questa stringa di formato arcaico? Quanto sarebbe più semplice fare: [_contentView constraint: NSLayoutFormatAlignLeading toView: self withDistance: 0.0f]; O qualcosa di simile? Mi piacerebbe così tanto fare lo con molle e montanti a questo punto.

Qualsiasi aiuto nella comprensione o la dimostrazione della sintassi per limitare il contenuto alla dimensione di sé sarebbe utile.

+2

Per quanto riguarda il tuo rant: l'Autolayout ha una curva di apprendimento e tu tendi a odiarlo all'inizio - ma una volta che pensi interamente ai vincoli invece che ai fotogrammi, diventa più facile. E il "formato visivo" è piuttosto inutile, a meno che non stiate mettendo le cose in fila. L'altro metodo (constraintWithItem ...) è fondamentalmente la sintassi che stai cercando nel tuo rant sopra. – jrturton

+0

Se qualcun altro ha problemi a capire questa stringa in formato ASCII, ho trovato utile questo tutorial. So che è per Ruby ma la stringa di formato è la stessa di Objective-C. http://seanlilusus.github.com – brucemartin

risposta

26

L'errore ti dice quello che è necessario sapere:

Fa il riferimento qualcosa di vincolo da fuori sottostruttura della vista?

Sì, sì.Fa riferimento alla sua superview.

Questi vincoli che devono essere applicati al superview, in questo caso lo groupView.

+0

Ok, ma questo non è un vincolo della sottoview? È la sottoview che ho bisogno di autorizzare. Sto solo pensando a questo torto? – brucemartin

+1

Pensateci in questo modo: è un vincolo per il posizionamento e la dimensione di 'contentView' all'interno di' groupView'. Vedere la sezione Installare i vincoli: http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AutolayoutPG/Articles/constraintFundamentals.html – jackslash

+0

ok, sì, lo vedo ora, ecco perché i vincoli in Xcode vengono mostrati sotto le superViste non la vista stessa. Ancora problemi di sintassi. Tornando ai documenti, forse affonderà in questo momento. Grazie per l'intuizione. – brucemartin

0

Il | personaggio rappresenta il superview nella lingua formato visivo, quindi penso che si desidera:

@"|-0-[_contentView]-0-|" 

e quindi è necessario aggiungere il vincolo di auto al posto del contentView, come è necessario aggiungerlo a una visione che può vedere tutti i giocatori coinvolti.

Qui è il riferimento per il linguaggio visivo: https://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AutolayoutPG/Articles/formatLanguage.html#//apple_ref/doc/uid/TP40010853-CH3-SW1

si può anche evitare il formato visivo del tutto utilizzando:

+(id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c 
+0

Sicuramente se si aggiunge il vincolo a self anziché a contentView, allora la pipe (|) farà riferimento alla superview di self? –

0

cercano controllare i constrints, siano essi a destra aggiungono alla vista

esempio:

UIView *yellowView = [[UIView alloc] init]; 
yellowView.backgroundColor = [UIColor yellowColor]; 
yellowView.translatesAutoresizingMaskIntoConstraints = false; 
[self.view addSubview:yellowView]; 

//ios 9 last 
NSLayoutConstraint *heightAnchor = [yellowView.heightAnchor constraintEqualToAnchor:self.purView.heightAnchor]; 
// addConstraints 
[self.view addConstraints:@[heightAnchor]]; 
[self.view setNeedsLayout]; 

se aggiungi heightAnchor toyellowView come segue. mostrerà l'errore

[yellowView addConstraints: @ [heightAnchor]];