2015-03-18 9 views
8

Spiegazione rapida.Il vincolo orizzontale non funziona correttamente in un UIScrollView. (vincoli programmatici)

Ho una UIScrollView, questa è una sotto-vista di "self.view". mio UIScrollview, ha una visualizzazione secondaria denominato contentView

tutti i miei altri oggetti sono subviews di contentView o è sub-views

Ho tutto guardare in modo corretto, con l'eccezione di 2 viste.

Dopo aver aggiunto queste viste nei miei vincoli. L'intero contentView si sposta a sinistra e interrompe tutto.

Ecco un'immagine dello schermo con la fastidiosa vista chiamata (howManyIconView), è il blu UIView, con un'icona di allentamento bianco nel mezzo. (in basso a sinistra)

Per rendere chiaro a tutti che è lo contentView che si sta rovinando, ho dato a contentView uno sfondo rosso.

enter image description here

Ecco la stessa vista, senza aggiungere il howManyIconView al mio vincolo.

enter image description here

Per il codice reale connessa al problema, partendo dall'alto.

contentView.setTranslatesAutoresizingMaskIntoConstraints(false) 
scrollView.addSubview(contentView) 

howManyContentView.setTranslatesAutoresizingMaskIntoConstraints(false) 
contentView.addSubview(howManyContentView) 

howManyIconView.setTranslatesAutoresizingMaskIntoConstraints(false) 
howManyIconView.backgroundColor = UIColor.formulaBlueColor() 
howManyContentView.addSubview(howManyIconView) 

howManyIcon.setTranslatesAutoresizingMaskIntoConstraints(false) 
howManyIcon.textColor = UIColor.formulaWhiteColor() 
howManyIcon.font = UIFont(name: "fontAwesome", size: 20) 
howManyIcon.text = "" 
howManyIconView.addSubview(howManyIcon) 

Ed ecco i vincoli:

var viewsDictionary = ["contentView":contentView,"howManyContentView":howManyContentView, 
      "howManyLabel":howManyLabel, 
      "howManyInputField":howManyInputField, 
      "howManyIconView":howManyIconView, 
      "howManyIcon":howManyIcon] 

    let metricsDictionary = ["topBarHeight":6,"numbersViewRowHeight":49,"numbersViewSeperatorHeight":1,"inputFieldHeight":75,"contentWidth":self.view.bounds.width,"grapViewHeight":175,"inputFieldWidth":100,"iconViewWidth":50] 

      scrollView.addConstraints(
      NSLayoutConstraint.constraintsWithVisualFormat(
       "H:[contentView(contentWidth)]", options: NSLayoutFormatOptions(0), metrics: metricsDictionary, views: viewsDictionary)) 

     howManyContentView.addConstraints(
      NSLayoutConstraint.constraintsWithVisualFormat(
       "V:[howManyIconView(inputFieldHeight)]", options: NSLayoutFormatOptions(0), metrics: metricsDictionary, views: viewsDictionary)) 
     howManyContentView.addConstraints(
      NSLayoutConstraint.constraintsWithVisualFormat(
       "V:[howManyInputField(inputFieldHeight)]", options: NSLayoutFormatOptions(0), metrics: metricsDictionary, views: viewsDictionary)) 

contentView.addConstraints(
      NSLayoutConstraint.constraintsWithVisualFormat(
       "H:|[howManyContentView]|", options: nil, metrics: nil, views: viewsDictionary)) 

     howManyContentView.addConstraint(NSLayoutConstraint(item:howManyLabel, attribute:NSLayoutAttribute.CenterY, relatedBy:NSLayoutRelation.Equal, toItem:howManyContentView, attribute:NSLayoutAttribute.CenterY, multiplier:1.0, constant:0)) 
     howManyContentView.addConstraint(NSLayoutConstraint(item:howManyInputField, attribute:NSLayoutAttribute.CenterY, relatedBy:NSLayoutRelation.Equal, toItem:howManyContentView, attribute:NSLayoutAttribute.CenterY, multiplier:1.0, constant:0)) 
     howManyContentView.addConstraint(NSLayoutConstraint(item:howManyIconView, attribute:NSLayoutAttribute.CenterY, relatedBy:NSLayoutRelation.Equal, toItem:howManyContentView, attribute:NSLayoutAttribute.CenterY, multiplier:1.0, constant:0)) 
     howManyIconView.addConstraint(NSLayoutConstraint(item:howManyIcon, attribute:NSLayoutAttribute.CenterY, relatedBy:NSLayoutRelation.Equal, toItem:howManyIconView, attribute:NSLayoutAttribute.CenterY, multiplier:1.0, constant:0)) 
     howManyIconView.addConstraint(NSLayoutConstraint(item:howManyIcon, attribute:NSLayoutAttribute.CenterX, relatedBy:NSLayoutRelation.Equal, toItem:howManyIconView, attribute:NSLayoutAttribute.CenterX, multiplier:1.0, constant:0)) 


     howManyContentView.addConstraints(
    NSLayoutConstraint.constraintsWithVisualFormat(
     "H:|-32-[howManyLabel]", options: nil, metrics: metricsDictionary, views: viewsDictionary)) 

Il vincolo di seguito, è quella che scombina tutto. Una volta rimosso [howManyIconView(iconViewWidth)] da quella riga di codice, è tutto a posto.

howManyContentView.addConstraints(
    NSLayoutConstraint.constraintsWithVisualFormat(
     "H:[howManyIconView(iconViewWidth)][howManyInputField(inputFieldWidth)]-32-|", options: nil, metrics: metricsDictionary, views: viewsDictionary)) 

Ho tripla verificato che howManyContentView, howManyIconView e howManyIcon non figurano in alcun codice non mostrato in questo post.

Ecco cosa ho cercato di risolvere il mio problema

Prima di tutto ho cercato di fare un altro vista chiamato HowManyInputView, dove ho messo la iconView e UITextField. Poi mettere che come l'unico vincolo. (stesso risultato)

Successivamente ho provato a rimuovere tutto ciò che aveva a che fare con lo UILabel all'interno di iconView. Per vedere se ha qualcosa a che fare con l'etichetta. (Stesso risultato)

Quindi ho provato a creare una nuova vista. e gli ha fornito vincoli di posizione simili (ma non uguali) (stesso problema), anche questa vista non ha avuto sottoview, dimostrando inoltre che è la vista e non lo UILabel a causare i miei problemi.

Così ho provato a dividere il mio vincolo orizzontale in 2. Prima come si può vedere nel codice. Gli ho dato una larghezza e un vincolo orizzontale nella stessa riga di codice. Quindi ho creato 2 linee di vincolo diverse, una per ridimensionarla orizzontalmente e una per posizionarla.(stesso risultato)

A questo punto ho esaurito le idee. Così ho cancellato la mia cartella dei dati derivati ​​e ripulito il mio progetto. (ancora non funzionante)

Avanti Ho provato a stampare i vincoli per la vista problematica. Utilizzando constraintsAffectingLayoutForAxis in questo modo:

println("Horizontal: \(howManyIconView.constraintsAffectingLayoutForAxis(UILayoutConstraintAxis.Horizontal))") 

println("Vertical: \(howManyIconView.constraintsAffectingLayoutForAxis(UILayoutConstraintAxis.Vertical))") 

e questo è ciò che la console stampe fuori:

Horizontal: [<NSLayoutConstraint:0x174299050 H:[UIView:0x17019df60(50)]>] 

Vertical: [<NSLayoutConstraint:0x17429aae0 V:|-(0)-[UIView:0x17019df60] (Names: '|':UIView:0x17019ddc0)>, <NSLayoutConstraint:0x17429ab30 V:[UIView:0x17019df60]-(0)-| (Names: '|':UIView:0x17019ddc0)>] 

A meno che non sto leggendo questo torto. Sembra che iconView riceva solo un vincolo di dimensionamento di (50) e non il vincolo orizzontale di posizione effettivo. Nonostante sia inserito correttamente accanto al mio UITextField?

Perché questo sta accadendo è ancora un mistero, per quanto posso vedere, il mio vincolo di posizionamento orizzontale dovrebbe andare bene. Non ricevo errori. Ma sperando di fornire la causa del mio problema, aiuterò a risolverlo.

Qualsiasi aiuto sarebbe molto apprezzato! (Nessuno dei miei tentativi hanno causato eventuali errori nella console.)

risposta

2

Ci sono 2 possibili errori che vedo:

  1. non vedo un vincolo per contentView a destra ea sinistra. Entrambi dovrebbero essere zero, credo. In caso contrario, la posizione di contentView sarà casuale in scrollView. Questo dovrebbe essere risolto sostituendo H:[contentView(contentWidth)] con H:|[contentView(contentWidth)]|

  2. usando self.view.bounds.width per contentView larghezza può essere un po 'rischioso - a seconda da quale metodo si sta chiamando esso. Sei sicuro che sia uguale alla dimensione dello schermo?

Si noti che, in generale, è più facile da configurare vincoli in Interface Builder, perché si avverte sempre di vincoli mancanti.

+0

cambiando il mio contenutoView a 'H: | [contentView (contentWidth)] |' ha risolto il mal di testa della settimana scorsa! Grazie mille. Non hai idea di quanto ciò abbia aiutato! Per quanto riguarda self.view.bounds.width, lo sto chiamando in viewDidLoad, sembra sempre adattarsi allo schermo. Per quanto riguarda IB, non uso storyboard, quindi i (limiti programmatici). –

+0

@MarkL Anche quando non si utilizzano gli storyboard, utilizzare IB per creare xibs con controller singolo è una buona idea. È solo più veloce e più facile da fare. Meno codice = migliore manutenzione. – Sulthan