"Unsupport this animation type!" exception
opened this issue · comments
With 0.66
this exception is thrown on very basic animation:
myView.makeAlpha(0.0)
.duration(aDuration)
.autoreverses()
.repeatCount(someRepetitions)
.completion {
// Some statements
myView.removeFromSuperview()
}
.animate()
Let's say it's a find of flash.
I tried other animation like makeSize
or makeColor
but same behavior.
This flash portion of code is called several times on a sequence basis. On the first call everything is fine. The exception is raises on the second call.
Between these two calls of flash there is an animation using CATransaction
. On the completion block of this animation the second call of flash is then made.
CATransaction.begin()
CATransaction.setCompletionBlock({
// call to flash animations
})
...
CATransaction.commit()
This error came after I decided to use CATransaction
to use it's completion block.
Can you provide this animation intact code in your project?
No, I can provide intact code as this is hard to achieve.
It seems the problem arise when mixing animations on the same UIView
subclass:
- animation using Stellar on
myView
— animateUIView
, - then custom keyframe animation on
CALayer
ofmyView
, — animateCALayer
, - animation using Stellar on
myView
, — animateUIView
,
The problem arises on step 3 with animation from Stellar on UIView
. The fatalError is invoked on createDynamicBehavior
on CALayer
extension on file CALayer+AnimateBehavior.swift
. Notice the curious behavior as error is raised on CALayer
part of Stellar but animation is set on UIView
!
In others words, why CALayer
is concerned in UIView
animation?
Before using explicit animations on CALayer
everything was fine: I then replace some animations done by Stellar by keyframes animations on CALayer
.
What is the unsupport animation's 'type'?
@AugustRush
This is alpha
.
And the animation is the one on the first issue card:
myView.makeAlpha(0.0)
.duration(aDuration)
.autoreverses()
.repeatCount(someRepetitions)
.completion {
// Some statements
myView.removeFromSuperview()
}
.animate()
So the alpha
is correct on call as this is an UIView
but become incorrect later on Stella as it is used for a CALayer
. So the question is: why this UIView
is treated as a CALayer
?
FYI breakpoint does not stop on fatalError invocation' line. Any idea?
Because all UIView's animation just it's layer's animation, you should not use alpha on CALayer,replace it with 'opacity'.
But I use alpha because myView
is an UIView
and there is not makeOpacity
for UIView
. The code is correct as makeAlpha is apply to UIView: the compilation wouldn't work if not.
It's like if somewhere in Stellar when using alpha for UIView
, the CALayer
is then used but alpha
is not "translate" to opacity
.
I found a trick to make it work by modifying Stellar. The goal is to treat alpha
for CALayer
and not raise an exception.
So I duplicate treatment for opacity
[1] and cast opacity
to alpha
[2]. So on createDynamicBehavior
on CALayer
extension on file CALayer+AnimateBehavior.swift
:
case .opacity(let o):
let from = self.opacity
let to = o
let render = {(f: Float) in
self.opacity = f
}
switch style {
case .basic:
behavior = basicBehavior(step, from: from, to: to, render: render)
case .attachment(let damping, let frequency):
behavior = attachmentBehavior(damping, frequency: frequency, from: from, to: to, render: render)
case .gravity(let magnitude):
behavior = gravityBehavior(magnitude, from: from, to: to, render: render)
case .snap(let damping):
behavior = snapBehavior(damping, from: from, to: to, render: render)
}
// [1]
case .alpha(let a):
let from = self.opacity
let to = Float(a) // [2]
let render = {(f: Float) in
self.opacity = f
}
switch style {
case .basic:
behavior = basicBehavior(step, from: from, to: to, render: render)
case .attachment(let damping, let frequency):
behavior = attachmentBehavior(damping, frequency: frequency, from: from, to: to, render: render)
case .gravity(let magnitude):
behavior = gravityBehavior(magnitude, from: from, to: to, render: render)
case .snap(let damping):
behavior = snapBehavior(damping, from: from, to: to, render: render)
}
So there must be a problem somewhere on Stellar!
Yes, must be somewhere has a problem.
Here are more details about this problem.
I noticed another weird behavior on animations on my app. After animations ended, animated UIViews are back to their initial states – the state before the animation occurred. For example, an UIView move from point A to point B then back to point A after the animation complete. This is a common behavior when using keyframe animations: differences between layer tree and presentation tree .
But in this case this occur after animations on UIViews made using Stellar. If I replace the Stellar animations by a class UIView animation block then everything work as expected.
Hope this lead you to the code of the problem!