问题
I composed a kind of animation by adding several layers to a UIView. Those layers shall be set visible or invisible by a script.
The script is based on objects that implement a protocol:
// the general protocol for a step
@protocol ActionStep
-(void) applyForTime:(int)playtime;
-(void) reset;
@end
an in a timer I iterate through the step objects:
NSEnumerator* enumerator = [ScriptObjects objectEnumerator];
id obj;
while ( obj = [enumerator nextObject] )
{
id <ActionStep> step = obj;
[step applyForTime:currentmilliseconds];
}
One script object is this object:
@interface LayerStep : NSObject <ActionStep>
{
int mTimeOffset;
CGPoint mOffset;
float mAlpha;
LayerObject* mTheLayer;
bool mPrepared;
}
-(id)initWithLayerObject: (LayerObject*) theLayer Milliseconds:(int) milliseconds Offset:(CGPoint) offset Alpha:(float)alpha;
@end
and finally I implement the protocol in the layer:
-(void) applyForTime:(int)playtime
{
if ( mPrepared ) // has the step already been executed?
{
if ( playtime >= mTimeOffset )
{
[mTheLayer setAlpha:mAlpha]; // AssignedLayer.opacity = alpha;
[mTheLayer setPosition:mOffset]; // AssignedLayer.position = offset;
mPrepared = false;
}
}
}
Applying the changes in the step results in a transition.
Is there a way to disable this transition? I am not using any CoreAnimation call at all right now, just the properties itself (see code).
回答1:
Changing one of a layer's "animatable" properties creates what Apple's docs calls an implicit animation.
To quote the Xcode docs on the subject:
Core Animation’s implicit animation model assumes that all changes to animatable layer properties should be gradual and asynchronous. Dynamically animated scenes can be achieved without ever explicitly animating layers. Changing the value of an animatable layer property causes the layer to implicitly animate the change from the old value to the new value. While an animation is in-flight, setting a new target value causes the animation transition to the new target value from its current state.
Under the covers, the system generates a CAAnimation that makes the change.
As the other poster said, you can use setAnimationDuration to make the animation happen in an instant, which has the effect of turning animations off. I suspect that the system still generates an animation however.
The official way to turn off implicit layer animations is to use
[CATransaction begin];
[CATransaction setDisableActions: YES];
//layer changes
[CATransaction commit];
Edit:
In Swift 3, this code would look like this:
CATransaction.begin()
CATransaction.setDisableActions(true)
//layer changes
CATransaction.commit()
回答2:
Just wrap the code where you are making the change.
[CATransaction begin];
[CATransaction setAnimationDuration:0];
[thelayer setAlpha:0];
[CATransaction commit];
来源:https://stackoverflow.com/questions/10155641/disabling-animation-when-changing-layer-view-properties