【发布时间】:2016-03-22 22:40:53
【问题描述】:
概述:我目前有一个实现自定义动画逻辑的自定义 UIView 子类,但我不确定视图类是否是放置该代码的最佳位置。
我正在 Swift 中制作一个 iOS 应用程序,它使用我称为 DoorView 的 UIView 子类。 DoorView 代表滑动门,它响应滑动手势执行滑动动画以打开。
这是我现在拥有的完整动画:
为了让我的视图控制器保持轻便,我将处理这些动画的实际核心动画代码放入我的 DoorView 类中。我的视图控制器通过检查手势是否匹配打开给定门所需的手势来处理手势,如果是,则调用 DoorView 上的 open() 方法。
所以在 ViewController 中:
@IBAction func swipe(sender: UISwipeGestureRecognizer) {
if (sender.direction.rawValue == currentDoorView.door.swipeDirection.rawValue) {
self.currentDoorView.open()
}
}
这是我的 DoorView 类中的 open() 方法: 注意:这只是滑动动画,以后会使用 Sliding-type 的检查来区分其他类型的门(例如铰链)。
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")
}
}
那么可以把动画逻辑放在视图类中吗?这是我的第一直觉,因为 a) 这些动画是特定于我的 DoorView,b) 因为 animateWithDuration 是 UIView 的一个类方法,所以似乎有一些动画由视图/视图类本身处理的先例。
但我会继续开发我的应用程序,我会添加更多带有自己动画的门类型,我担心 DoorView 会因为动画代码而变得过于臃肿。那时我是否应该开始制作 DoorView 子类(即 SlidingDoorView、HingedDoorView 等)?
或者视图动画应该由视图控制器处理?除了 VC 膨胀之外,我的问题是,如果我想在其他视图控制器中使用 DoorViews,我需要复制代码。这样一来,我的 DoorViews 就包含了它们自己的动画,而我的 VC 需要做的就是调用 open()。
【问题讨论】:
-
不错的动画。听起来每个动画都应该是它自己的类。你从什么子类化它取决于需要重用什么代码。
-
啊,有趣!感谢您的答复。在那种情况下,动画会在哪里调用?我是否仍然在我的 DoorView 类中处理这些动画方法调用,还是在 View Controller 中处理它更有意义?
-
如果您可以将它们封装在 View 类中,它们将更容易在其他控制器中使用。
-
太好了,这也是我的直觉。
标签: ios animation design-patterns core-animation cocoa-design-patterns