2015-12-10 1 views
0

J'ai un problème avec la façon dont UIViews sont mis en place.Le cadre de UIView est écrasé au hasard

Situation

J'ai vue que je vais ajouter des vues de détail à. Ces vues de détail sont dans l'ordre séquentiel, tout comme les lignes d'un UITableView sont. C'est en fait une très bonne comparaison. La différence est que dans cette vue, nous ne faisons pas défiler de haut en bas mais de travers.

De ces vues détaillées, il y en a toujours une à l'écran. Lorsque j'ajoute ce premier écran, je charge aussi le suivant (vers la droite) et je le retire de l'écran (encore une fois, vers la droite). Lorsque l'utilisateur appuie sur un bouton, nous passons à la vue suivante avec une petite animation. La dernière vue visible glisse vers la gauche et de la droite la seconde vue entre. A ce moment, je garde une référence à la gauche et j'en charge une neuve de droite, s'il y en a. J'ai créé un protocole fait de tout autre objet la source de données pour ce que j'appelle le SlidableDetailViewController (SDVC).

Actuellement, je configure les vues de détail au cours de la source de données didSet. Au cours de cette configuration, il génère ces trois images (encore une fois, celles de gauche, de centre et de droite).

Problème

Lorsque les charges de vue et apparaît d'abord sur l'écran, le cadre de la vue centrale est pas ce qu'elle devrait être, mais beaucoup plus petit. La deuxième vue de détail sera affichée correctement. Quand je reviens au premier, le cadre sera mis à jour et correct aussi.

Lorsque je le débogue, les images sont calculées et définies correctement. Quand je casse viewWillAppear(_:), même le cadre de la vue est ce que j'attends. Quand je fais la même chose en viewDidAppear(_:), il était déjà réduit à cette taille étrange que personne ne voulait. Je ne fais rien dans ceux-là; Je les ai juste utilisés pour déboguer dans le code ici.

Est-ce que quelqu'un voit ce que je fais mal ici? Je suis à peu près sûr que c'est juste une erreur stupide de ma part, mais je n'arrive pas à comprendre pourquoi.

Mise à jour des exemples de code

Calcul des cadres:

private func calculateFrames() { 
    // Get the size for our views from the dataSource. 
    let detailViewSize: CGSize 
    if let theDataSource = dataSource { 
     detailViewSize = theDataSource.detailViewSize() 
    } else { 
     // Just use a few default values. 
     detailViewSize = CGSizeMake(320, 185) 
    } 

    // Calculate the frame for on screen display. 
    let detailFrameX = (view.frame.width - detailViewSize.width)/2 
    let detailFrameY = (view.frame.height/2 - detailViewSize.height/2) 
    centerFrame = CGRectMake(detailFrameX, detailFrameY, detailViewSize.width, detailViewSize.height) 

    // The other two frames are basically just offsets of the original centerFrame. 
    leftFrame = centerFrame?.offsetBy(dx: (detailViewOffset * -1), dy: 0.0) 
    rightFrame = centerFrame?.offsetBy(dx: detailViewOffset, dy: 0.0) 
} 

Chargement de la vue suivante (chargement de la vue précédente fonctionne à peu près de la même façon):

func showNextDetailView() { 
    // 1. If we're at the last item, we can't advance. 
    if selectedIndex == detailsCount() - 1 { 
     return 
    } 

    // 2. Check if there is a view on the left spot 
    if leftView != nil { 
     // 2.1. … if so, remove it from superView. 
     leftView?.removeFromSuperview() 
    } 

    UIView.animateWithDuration(animationDuration, delay: 0.0, options: .CurveEaseInOut, animations: {() -> Void in 
     // 3. Set the frame of the view at selectedIndex to leftFrame. 
     self.centerView?.frame = self.leftFrame! 
     // 4. Set the frame of the view at selectedIndex + 1 to center frame. 
     self.rightView?.frame = self.centerFrame! 
     }) { (finished) -> Void in 
      print("animation to next detail view finished") 
    } 

    // 5. Increase the selectedIndex 
    selectedIndex++ 

    // Store the new positions for quick reference. 
    if let theDataSource = dataSource { 
     if let newLeftView = theDataSource.detailViewAtIndex(selectedIndex - 1) { 
      leftView = newLeftView 
     } 

     if let newCenterView = theDataSource.detailViewAtIndex(selectedIndex) { 
      centerView = newCenterView 
     } 

     // 6. Check if we have more views left 
     if detailsCount() - 1 > selectedIndex { 
      // 6.1 … and if so, add a new one to the right. 
      rightView = theDataSource.detailViewAtIndex(selectedIndex + 1) 
      rightView?.frame = rightFrame! 
      contentView.addSubview(rightView!) 
     } else { 
      rightView = nil 
     } 
    } 
} 

Remerciez toi!

+1

Pourriez-vous donner un exemple du code que vous utilisez pour configurer ces cadres et vous déplacer entre eux? En outre, vous pouvez utiliser une vue de collection avec une disposition de flux standard pour les vues de défilement latéral comme cela, si cela vous convient. –

+0

Bien sûr, s'il vous plaît voir le post mis à jour. L'idée d'utiliser un 'UICollectionView' ne m'a jamais traversé l'esprit car je pensais à eux comme une vue de grille qui ne se prête pas à l'utiliser de manière linéaire, de gauche à droite. Si c'est le cas, cela pourrait être un excellent moyen de se débarrasser d'une grande partie de mon code.Je dois regarder dans ceci. Merci pour cet indice! – flohei

+1

Merci, et oui, UICollectionViewFlowLayout correspond littéralement à un affichage linéaire, de gauche à droite. Vous pouvez définir la direction de défilement sur la mise en page comme étant .horizontale. Vous pourriez économiser un peu d'effort et les vues réutilisables sont toujours bonnes! –

Répondre

0

J'ai été en mesure de résoudre ce problème en utilisant le UIPageViewController ordinaire comme suggéré par rob mayoff.