Vue d'ensemble: J'ai actuellement une sous-classe UIView personnalisée qui implémente la logique d'animation personnalisée, et je ne suis pas sûr que la classe de vue est le meilleur endroit pour mettre ce code.Où devrait aller le code d'animation personnalisé et réutilisable?
Je crée une application iOS dans Swift qui utilise une sous-classe UIView que j'appelle DoorView. Un DoorView représente une porte coulissante qui, en réponse à un geste de balayage, effectue une animation coulissante à ouvrir.
Voici une animation complète que je l'ai maintenant:
En essayant de garder mon point de vue la lumière du contrôleur, je mets le code d'animation de base réelle qui gère ces animations dans ma classe DoorView. My View Controller gère le mouvement en vérifiant s'il correspond au geste requis pour ouvrir une porte donnée, et si c'est le cas, appelle une méthode open() sur DoorView.
Ainsi, dans ViewController:
@IBAction func swipe(sender: UISwipeGestureRecognizer) {
if (sender.direction.rawValue == currentDoorView.door.swipeDirection.rawValue) {
self.currentDoorView.open()
}
}
Et voici la méthode ouverte() dans ma classe DoorView: Note: Ceci est juste l'animation de glissement, et le contrôle d'un type coulissant sera utilisé dans la l'avenir de se différencier des autres types de portes (par exemple à charnière).
func open(withDuration duration: CFTimeInterval = 1.0) {
/// We only slideOpen if switch statement below determines self.door is Sliding,
/// so we downcast as SlidingDoor so we can switch on door.slideDirection.
/// For each slideDirection case, a different translation is created,
/// which is then passed into the slideAnimation below.
func slideOpen() {
let slidingDoor = self.door as! SlidingDoor
let translation: CATransform3D
switch slidingDoor.slideDirection {
case .Down:
let height = baseLayer.bounds.height
translation = CATransform3DMakeTranslation(0, height, 0)
case .Left:
let width = openingLayer.bounds.size.width
translation = CATransform3DMakeTranslation(-width, 0, 0)
case .Right:
let width = openingLayer.bounds.size.width
translation = CATransform3DMakeTranslation(width, 0, 0)
case .Up:
let height = baseLayer.bounds.height
translation = CATransform3DMakeTranslation(0, -height, 0)
}
let slideAnimation = {
(completion:(() ->())?) in
CATransaction.begin()
CATransaction.setCompletionBlock(completion)
CATransaction.setAnimationDuration(duration)
self.openingLayer.transform = translation
CATransaction.commit()
}
/// Actual call to slideAnimation closure.
/// Upon completion, notify delegate and call walkThroughDoor()
slideAnimation({
self.delegate?.doorDidOpen(self)
self.walkThroughDoor()
})
}
/// Switch to determine door type, and thus appropriate opening animation.
switch self.door {
case is Sliding:
slideOpen()
default:
print("is not sliding")
}
}
Alors, est-il correct de mettre la logique d'animation dans une classe de vue? C'était mon premier instinct car a) ces animations sont spécifiques à mon DoorView, et b) parce que animateWithDuration est une méthode de classe de UIView, donc il semble y avoir un précédent pour que les animations soient gérées par les classes vues/vues elles-mêmes.
Mais je continue à développer mon application, je vais ajouter plus de types de portes avec leurs propres animations, et je crains que DoorView devienne trop gros avec le code d'animation. Devrais-je commencer à créer des sous-classes DoorView (c'est-à-dire SlidingDoorView, HingedDoorView, etc.)?
Ou les animations doivent-elles être gérées par le contrôleur de vue? Mon problème avec cela, en plus de VC bloat, est que si je veux utiliser DoorViews dans d'autres contrôleurs de vue, j'ai besoin de dupliquer le code. De cette façon, mes DoorViews sont livrés avec leurs propres animations et tout ce que mes VC doivent faire est d'appeler open().
Belle animation. On dirait que chaque animation devrait être sa propre classe. Ce que vous sous-classez dépend de quel code doit être réutilisé. – dbugger
Ah, intéressant! Merci pour votre réponse. Dans ce cas, où seraient appelées les animations? Serais-je toujours en train de gérer ces appels de méthodes d'animation dans ma classe DoorView, ou cela aurait-il plus de sens de le traiter dans un View Controller? –
Si vous pouvez les encapsuler dans la classe View, ils seront plus faciles à utiliser dans d'autres contrôleurs. – dbugger