Обзор: В настоящее время у меня есть пользовательский подкласс UIView, который реализует логику пользовательской анимации, и я не уверен, что класс представления - лучшее место для размещения этого кода.Где должен быть выполнен код, многоразовый код анимации?
Я делаю приложение iOS в Swift, которое использует подкласс UIView. Я вызываю DoorView. Дверь ViewView представляет собой раздвижную дверь, которая в ответ на жест скольжения выполняет скользящую анимацию для открытия.
Вот полный анимации, как я сейчас:
В попытке сохранить мой View Controller свет, я ставлю фактический основной код анимации, который обрабатывает эти анимации в моем классе DoorView. My View Controller обрабатывает жест, проверяя, соответствует ли он жест, необходимый для открытия данной двери, и если это так, вызывает метод open() в DoorView.
Так в ViewController:
@IBAction func swipe(sender: UISwipeGestureRecognizer) {
if (sender.direction.rawValue == currentDoorView.door.swipeDirection.rawValue) {
self.currentDoorView.open()
}
}
А вот открытым способом() в моем классе DoorView: Примечание: это только скользящая анимация, и проверка на Sliding-типа будет использоваться в будущее для дифференциации от других типов дверей (например, навесное).
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")
}
}
Так можно ли положить анимационную логику в класс представления? Это был мой первый инстинкт, потому что: а) эти анимации специфичны для моего DoorView и b) потому что animateWithDuration - это метод класса UIView, поэтому кажется, что некоторые анимации обрабатываются самими видами/представлениями.
Но я продолжаю разрабатывать свое приложение, я буду добавлять больше типов дверей с их собственными анимациями, и я опасаюсь, что DoorView станет слишком толстым с анимационным кодом. Должен ли я в этот момент просто начать создавать подклассы DoorView (т. Е. SlidingDoorView, HingedDoorView и т. Д.)?
Или следует просматривать анимацию с помощью контроллера вида? Моя проблема с этим, помимо VC bloat, заключается в том, что если я хочу использовать DoorViews в других контроллерах представлений, мне нужно будет дублировать код. Таким образом, мои DoorViews поставляются в комплекте с их собственной анимацией, и все мои VC, которые нужно сделать, это вызов open().
Хорошая анимация. Кажется, каждая анимация должна быть ее собственным классом. То, что вы подклассифицируете, зависит от того, какой код нужно повторно использовать. – dbugger
А, интересно! Спасибо за ваш ответ. В этом случае, где будут вызваны анимации? Должен ли я по-прежнему обрабатывать вызовы методов анимации в моем классе DoorView, или было бы разумнее, чтобы это обрабатывалось в контроллере просмотра? –
Если вы можете инкапсулировать их в класс View, они будут проще использовать в других контроллерах. – dbugger