Übersicht: Ich habe derzeit eine benutzerdefinierte UIView-Unterklasse, die benutzerdefinierte Animationslogik implementiert, und ich bin mir nicht sicher, ob die Ansichtsklasse der beste Ort ist, um diesen Code zu platzieren.Wohin soll benutzerdefinierter, wiederverwendbarer Animationscode gehen?
Ich mache eine iOS-App in Swift, die eine UIView-Unterklasse namens DoorView verwendet. Ein DoorView stellt eine Schiebetür dar, die als Antwort auf eine Wischgeste eine Schiebeanimation zum Öffnen ausführt.
ist die komplette Animation, wie ich es habe jetzt:
Bei dem Versuch, meinen View Controller Licht zu halten, habe ich den eigentlichen Kern Animation Code zu setzen, die diese Animationen in meine DoorView Klasse behandelt. Der View-Controller behandelt die Geste, indem er überprüft, ob sie mit der zum Öffnen einer bestimmten Tür erforderlichen Geste übereinstimmt, und ruft in diesem Fall eine open() -Methode für die Türansicht auf.
So in Viewcontroller:
@IBAction func swipe(sender: UISwipeGestureRecognizer) {
if (sender.direction.rawValue == currentDoorView.door.swipeDirection.rawValue) {
self.currentDoorView.open()
}
}
Und hier ist die Methode open() in meinem DoorView Klasse: Hinweis: Dies ist nur die gleitende Animation, und die Prüfung für einen Sliding-Typ wird in die verwendet werden, Zukunft von anderen Arten von Türen zu unterscheiden (zB klappbar).
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")
}
}
Also ist es in Ordnung, Animationslogik in einer Ansichtsklasse zu setzen? Es war mein erster Instinkt, weil a) diese Animationen spezifisch für mein DoorView sind, und b) weil animateWithDuration eine Klassenmethode von UIView ist, also scheint es einen Präzedenzfall für Animationen zu geben, die von Views/View-Klassen selbst gehandhabt werden.
Aber ich entwickle weiterhin meine App, ich werde mehr Türtypen mit ihren eigenen Animationen hinzufügen, und ich fürchte, DoorView wird mit Animationscode zu dick werden. Soll ich zu diesem Zeitpunkt DoorView-Unterklassen erstellen (d. H. SlidingDoorView, HingedDoorView usw.)?
Oder sollten Animationen vom View-Controller behandelt werden? Mein Problem damit, neben VC Bloat, ist, dass, wenn ich DoorViews in anderen View-Controllern verwenden möchte, ich Code duplizieren muss. Auf diese Weise werden meine DoorViews mit eigenen Animationen ausgeliefert und alle meine VCs müssen open() aufrufen.
Schöne Animation. Klingt wie jede Animation sollte eine eigene Klasse sein. Was Sie davon ableiten, hängt davon ab, welcher Code wiederverwendet werden muss. – dbugger
Ah, interessant! Vielen Dank für Ihre Antwort. In welchem Fall würden die Animationen aufgerufen? Würde ich immer noch diese Aufrufe der Animationsmethode in meiner DoorView-Klasse behandeln, oder würde es mehr Sinn machen, sie in einem View-Controller zu behandeln? –
Wenn Sie sie in der View-Klasse kapseln können, wären sie einfacher in anderen Controllern zu verwenden. – dbugger