2015-08-05 15 views
5

Ho una vista di scorrimento annidata all'interno di un controller di visualizzazione che si trova in un contenitore. Il View Controller, che utilizza una classe specificata chiamato ScrollingViewController assomiglia a questo:Vincoli di layout automatico iOS e frame non funzionanti

class ScrollingViewController: UIViewController { 

    @IBOutlet weak var scrollView: UIScrollView! //outlet for the Scroll View 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // 1) Create the two views used in the swipe container view 
     var storyboard = UIStoryboard(name: "App", bundle: nil) 
     var subOne: SubProfileOneViewController = storyboard.instantiateViewControllerWithIdentifier("subone") as! SubProfileOneViewController 
     var subTwo: SubProfileTwoViewController = storyboard.instantiateViewControllerWithIdentifier("subtwo") as! SubProfileTwoViewController 

     // 2) Add in each view to the container view hierarchy 
     // Add them in opposite order since the view hierarchy is a stack 
     self.addChildViewController(subTwo); 
     self.scrollView!.addSubview(subTwo.view); 
     subTwo.didMoveToParentViewController(self); 

     self.addChildViewController(subOne); 
     self.scrollView!.addSubview(subOne.view); 
     subOne.didMoveToParentViewController(self); 

     // 3) Set up the frames of the view controllers to align 
     // with each other inside the container view 
     var adminFrame :CGRect = subOne.view.frame; 
     adminFrame.origin.x = adminFrame.width; 
     subTwo.view.frame = adminFrame; 

     // 4) Finally set the size of the scroll view that contains the frames 
     var scrollWidth: CGFloat = 2 * self.view.frame.width 
     var scrollHeight: CGFloat = 262 
     self.scrollView!.contentSize = CGSizeMake(scrollWidth, scrollHeight); 
     // Do any additional setup after loading the view. 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 
} 

In sostanza quello che sta succedendo è che due Visualizza i controllori che utilizzano tale classe SubProfileOneViewController e SubProfileTwoViewController rispettivamente, vengono istanziati come subOne e subTwo. Questi vengono quindi aggiunti alla Vista di scorrimento come bambini al fine di creare un'interfaccia in cui l'utente può scorrere verso destra per accedere a un'altra vista (quasi come Snapchat). subOne e subTwo devono essere affiancati e l'utente dovrebbe essere in grado di scorrere da uno a quello successivo e viceversa.

Ecco cosa tutto questo appare come il mio storyboard: enter image description here

SubProfileOneViewController e SubProfileTwoViewController ogni avere una vista (rappresentato da verde e rosso rispettivamente) e hanno ciascuno gli stessi vincoli precisi, che sono: Altezza = 262, Trailing spazio a superview = 0, Spazio principale a superview = 0, Spazio superiore a superview = 0

Idealmente, quando eseguito, ci dovrebbero essere due viste, una verde e una rossa e l'utente dovrebbe essere in grado di scorrere tra ciascuna . Tuttavia, ecco ciò che effettivamente accade: enter image description here

I punti di vista verde e rossa non occupano l'intera larghezza dello schermo e invece sono condensati in un piccolo frammento a sinistra, e la maggior parte della vista controllori sono bianchi, invece di il loro colore rispettivo. Ho provato molte cose e non sono sicuro di cosa sto sbagliando.

(credito per il codice in ScollingViewController va a lbrendanl su GitHub, collegati qui: https://github.com/lbrendanl/SwiftSwipeView)

+0

quali vincoli sono stati utilizzati per le viste del contenitore all'interno di scrollview. puoi pubblicare un progetto di esempio? –

+0

Vorrei aggiungere un singolo UIView (contentView) al tuo 'UIScrollView'. Quindi aggiungi le visualizzazioni del controller figlio all'interno della visualizzazione del contenuto. Aggiungi i vincoli per le tue visuali secondarie che pongono il loro lato superiore e inferiore alla vista del contenuto. Per visualizzarne uno, collegare il leader alla vista del contenuto, quindi pin il suo trascinamento per visualizzare due leader. Finalmente la visualizzazione pin due finali alla vista del contenuto. Per forzare le larghezze a destra sono necessari vincoli per la larghezza per la vista uno e la vista due: o aggiungere un vincolo di larghezza per contentView per essere la schermata x2 e aggiungere vincoli per la vista uno e visualizzare due per avere larghezza uguale. –

risposta

2

Nota:Ti consiglio di utilizzare una soluzione Autolayout, che gestirà automaticamente i cambiamenti di orientamento, dimensioni dello schermo, tutte con molto meno codice e soluzione più robusta di quella che sviluppo sotto.

Con l'approccio corrente, utilizzando incorporatoUIViewControllers, è necessario attendere che questi controller per completare i loro rispettivi inizializzazioni, che sono in diretta concorrenza con il layout. Si noti che sarà necessario ricalcolare le posizioni + le dimensioni in base alle modifiche di orientamento. Ancora una volta, mentre questo funziona, è non un sound design dal momento che richiede un sacco di codice, logica e funzionalità generali che otterresti gratis usando NSLayoutConstraint.

(testato, costruito, legato e corse):

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 

    // 3) Set up the frames of the view controllers to align 
    // with each other inside the container view 
    var adminFrame = self.view.frame 
    subOne.view.frame = adminFrame 
    adminFrame.offset(dx: self.view.frame.width, dy: 0) 
    subTwo.view.frame = adminFrame; 

    // 4) Finally set the size of the scroll view that contains the frames 
    let scrollWidth = 2 * self.view.frame.width 
    self.scrollView!.contentSize = CGSizeMake(scrollWidth, self.view.frame.height) 
} 

Ecco lo scorrimento (in azione). Si noti che ho creato le viste della classe ViewLayoutAssistant.swift che consente di visualizzare la posizione + la scala in modo conveniente.

enter image description here

Inoltre non c'è bisogno di dire la vista la sua gerarchia è cambiata.Questo ultimo pezzo di codice dovrebbe farti andare:

@IBOutlet weak var scrollView: UIScrollView! 
weak var subOne: SubProfileOneViewController! 
weak var subTwo: SubProfileTwoViewController! 

    self.addChildViewController(subTwo); 
    self.scrollView!.addSubview(subTwo.view); 
    self.addChildViewController(subOne); 
    self.scrollView!.addSubview(subOne.view); 
2

ScrollView con il layout automatico funziona in modo diverso o si può utilizzare solo una visualizzazione secondaria impostando translatesAutoresizingMaskIntoConstraints = true e l'impostazione contentSize esplicitamente. Oppure imposta translatesAutoresizingMaskIntoConstraints = false e lascia che lo scopra autonomamente. Visita questo link per maggiori dettagli

Come volete entrambi dovrebbero prendere schermo intero, allora avete bisogno di aggiungere AutoLayoutConstraints, qualcosa di simile

  1. Pin Greenview lasciato a vista eccellente
  2. larghezza
  3. Set Greenview per stessa scrollViewWidth cioè bounds.size.width (non contetnSizeWidth)
  4. Pin Redview sinistra a destra GREENVIEW
  5. set Redview valore di larghezza uguale scrollViewWidth cioè bounds.size.width (non contetnSize.width)
Problemi correlati