2017-09-20 4 views
0

J'ai un problème étrange qui semble assez facile à résoudre. Je pense que je pourrais utiliser une solution de contournement pour être en mesure d'avoir le comportement que je veux, mais je veux savoir s'il y a une meilleure façon de le faire.Animation UIView avec autolayout et vues enfants

J'ai une vue appelée contentView (bleu dans l'image) qu'il va augmenter sa hauteur en utilisant un UIView.animation, ce n'est pas un problème du tout et fonctionne comme prévu.

Le problème ici est que ce point de vue a une composante de l'enfant (un bouton) qui a une contrainte autolayout à son fond égal à 22 comme ceci:

contentView with the button

Ceci est la contrainte autolayout:

enter image description here

Si je fais la hauteur sans redimensionne l'animation, il fonctionne très bien, le changement de vue en hauteur et le bouton sont toujours 22 points du fond du contentView. Mais lorsque j'utilise une animation pour rendre ce changement plus fluide et plus convivial, le bouton se déplace vers la position finale avant même que l'animation ne commence.

enter image description here

Je veux savoir comment je pourrais réaliser une animation en douceur ici, mais avec le bouton se déplaçant le long de sa vue parent

La partie du code qui gère l'animation est assez simple mais je vais le poster ici:

@IBAction func openDetail(_ sender: ExpandCourseDetail) { 
     let rotation = sender.getOpen() ? CGAffineTransform.identity : CGAffineTransform(rotationAngle: CGFloat.pi) 
     UIView.animate(withDuration: 0.5, delay: 0.1, options: [.curveEaseInOut], animations: { 
      sender.transform = rotation 
     }, completion: { 
      success in 
      sender.setOpen(!sender.getOpen()) 
     }) 
     UIView.animate(withDuration: 1.0, delay: 0.5, options: [.curveEaseInOut], animations: { 
      self.contentView.frame.size.height = sender.getOpen() ? self.contentView.frame.height - 300 : self.contentView.frame.height + 300 
     }, completion: nil) 
    } 

Comme une note de côté, le bouton lui-même a une animation qui tourne le bouton 180 degrés pour montrer à l'utilisateur que la vue est en pleine expansion.

Merci beaucoup pour votre aide.

+0

Vous pouvez essayer de modifier la hauteur de contentView en modifiant la propriété heightConstraint.constant au lieu de définir la taille de l'image. Je ne sais pas si ça va fonctionner. (Vous devez définir la contrainte avant animateWithDuration, puis appeler view.layoutIfNeeded dans le bloc d'animation.) –

+0

Ne modifiez pas l'image contentView qui est inutile si vous utilisez la mise en page automatique. Donnez une contrainte de hauteur et essayez d'ajuster la valeur constante et appelez self.view.layoutIfNeeded() et épinglez votre bouton à ce contenuvView bottom – karthikeyan

Répondre

2

C'est super facile avec des contraintes, il suffit de créer une IBOutlet de contrainte de hauteur superView et de changer sa valeur constante.

@IBAction func btnPressed(_ sender: UIButton) { 
    self.toggleButton.isSelected = !sender.isSelected 

    //Animation starts here 
    self.view.layoutIfNeeded() 
    UIView.animate(withDuration: 0.7) { 

     if self.toggleButton.isSelected { 
      //transform button 
      self.toggleButton.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi)) 

      //change your ParentView height to desired one 
      self.constContentViewHeight.constant = self.view.frame.size.height - 220 
      self.view.layoutIfNeeded() 
     } else { 

      self.toggleButton.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi*2)) 
      // Set height constraint to original value 
      self.constContentViewHeight.constant = 250 
      self.view.layoutIfNeeded() 
     } 
    } 

} 

J'ai créé une démo, vérifiez-la.

demo

+0

Merci @NSIceCode votre solution fonctionne :) – neteot

0

Le problème que vous rencontrez est dû à deux blocs d'animation. J'ai donc changé quelques lignes et mis en deux la transformation du bouton et l'animation en hauteur dans un bloc d'animation.

func openDetail(_ sender: ExpandCourseDetail) { 

    let isOpen = sender.getOpen() ? CGAffineTransform.identity : CGAffineTransform(rotationAngle: CGFloat.pi) 

    UIView.animate(withDuration: 1.0, delay: 0.5, options: [.curveEaseInOut], animations: { 

     sender.transform = rotation 
     self.contentView.frame.size.height = self.contentView.frame.height + (isOpen ? 300 : -300) 

    }, completion: { (success) in 
     sender.setOpen(!isOpen) 
    }) 
}