How do I get CATransition to actually work?

  • Now that the NDA has been lifted, I can finally ask a burning
    question...

    In Leopard, the new CATransition class supposedly animates a
    CoreImage transition onto a layer. Has anyone figured out how to get
    this to work in a similar style to how the transitions work in
    CoreImage Fun House?

    I set up my filter, set it in a transition, set the transition to
    render into the view's layer, then called -setWantsLayer: on the view
    to turn on the animation. Instead of showing the transition, the view
    turned white.

    I was able to work around this, and get Tiger compatibility, by
    falling back on the old NSAnimation class and a custom view to
    manually draw the transition to the screen. But the frame rate is
    really bad on any CPU slower than a 2 GHz Core Duo, which is why I
    was hoping to get CATransition working one of these days...

    Nick Zitzmann
    <http://www.chronosnet.com/>
  • On Oct 26, 2007, at 9:07 PM, Nick Zitzmann wrote:

    > Now that the NDA has been lifted, I can finally ask a burning
    > question...
    >
    > In Leopard, the new CATransition class supposedly animates a
    > CoreImage transition onto a layer.

    I'm assuming you're using layers directly, rather than the new
    animation proxies..

    Anyways, transitions don't exactly animate a Core Image transition
    onto the content of a layer.

    But, you can render filters onto layer content using the filters
    property. (and you can animate that). This is how the Core Animation
    Menu example from WWDC does it, but in that case you don't need to use
    transitions.

    What are you trying to accomplish? have the content swapped out? Does
    the animation occur in response to the layer being removed from the
    hierarchy?

    (I ask because the Core Animation Cookbook documentation will grow
    more effectively for users if I can get input on what people are
    having issues with)

    > Has anyone figured out how to get this to work in a similar style to
    > how the transitions work in CoreImage Fun House?
    >
    >
    > I set up my filter, set it in a transition, set the transition to
    > render into the view's layer, then called -setWantsLayer: on the
    > view to turn on the animation. Instead of showing the transition,
    > the view turned white.

    Did you create a layer instance and set it as the view's layer?

    Or does your custom view subclass implement the drawRect: method? That
    may wipe your view empty.

    Did you try it using one of the stock transitions? That would help
    determine if it is how you're configuring the filter, or if it's
    something else.

    just as a rule

    layer-backed views are views that use Core Animation backing
    (setWantsLayer: is Yes) and you let NSView manage the entire
    underlying layer hierarchy.  You stick to using View methods and such.

    layer-hosting views are views that you create a CALayer, set it as the
    layer, and then turn on setWantsLayer:.  Then you are responsible for
    all the layer management.

    >
    >
    > I was able to work around this, and get Tiger compatibility, by
    > falling back on the old NSAnimation class and a custom view to
    > manually draw the transition to the screen. But the frame rate is
    > really bad on any CPU slower than a 2 GHz Core Duo, which is why I
    > was hoping to get CATransition working one of these days...

    If you have an example, send it to me off-list. Or ping me off list.
  • > In Leopard, the new CATransition class supposedly animates a
    > CoreImage transition onto a layer. Has anyone figured out how to get
    > this to work in a similar style to how the transitions work in
    > CoreImage Fun House?

    Here is the implementation code of a NSView Subclass that replaces the
    standard "contents" animation (a fade) with a moveIn from right
    Transition

    Make a new view class (TransitionView), paste in the following code
    (replacing all the implementation code in the template), set the
    header up accordingly. Make a new custom view in IB, and set the class
    to TransitionView. You'll need to find your own images (image.png and
    Blue.tiff in the example.. easy to change though) and add them to the
    project

    Add two buttons, one labeled purple, one labeled blue.  Set them so
    that their target object is the view, and so that the appropriate ones
    trigger the appropriate changeTo...: action. It does it the easiest
    way, by creating an NSDictionary and setting the transition animation
    as the value for the "contents" key.  This replaces the stock implicit
    animation with the new one.

    Anyways, all of that is for the benefit of list readers.. I've sent
    you the code.

    Does this help at all?

    Can you please file a bug asking for an example in the Core Animation
    Cookbook documentation on how to "use a custom filter as a transition"?

    - (void)awakeFromNib
    {
    // setup the layers
    [self setupLayers];
    }

    - (void)setupLayers
    {
    rootLayer =[[CALayer layer] retain];
    // set the layer for the view class that we've customized
    [self setLayer:rootLayer];

    // turn on layer-hosting for the view. The order of these two
    // methods is important. For layer-hosting you want to set the layer
    // and then turn on the layer support for the view. For layer-
    backing, you
    // do the reverse
    [self setWantsLayer:YES];
    rootLayer.backgroundColor=CGColorCreateGenericRGB(1.0f,1.0f,1.0f,1.0f);
    rootLayer.borderWidth=1.0;


    frontLayer=[[CALayer layer] retain];
    frontLayer.bounds=rootLayer.bounds;
    frontLayer.position=rootLayer.position;
    frontLayer.contentsGravity=kCAGravityCenter;
    [rootLayer addSublayer:frontLayer];


    [self changeToBlue:self];
    [self setNewContentsAnimation:self];

    }

    -(void)setNewContentsAnimation:(id)sender
    {
    CATransition *theTransition=[CATransition animation];
    theTransition.type=kCATransitionMoveIn;
    theTransition.subtype=kCATransitionFromRight;
    NSMutableDictionary *theActions=[NSMutableDictionary
    dictionaryWithDictionary:[frontLayer actions]];
    [theActions setObject:theTransition forKey:@"contents"];
    frontLayer.actions=theActions;
    }

    - (void)changeToPurple:(id)sender;
    {
    NSImage *animatedImage=[[NSImage alloc] initWithContentsOfFile:
    [[NSBundle mainBundle] pathForResource:@"image" ofType:@"png"]];
    frontLayer.contents=(id)[[[animatedImage representations]
    objectAtIndex:0] CGImage];
    [animatedImage release];

    }

    - (void)changeToBlue:(id)sender
    {
    NSImage *animatedImage=[[NSImage alloc] initWithContentsOfFile:
    [[NSBundle mainBundle] pathForResource:@"Blue" ofType:@"tiff"]];
    frontLayer.contents=(id)[[[animatedImage representations]
    objectAtIndex:0] CGImage];
    [animatedImage release];

    }
  • On Oct 27, 2007, at 1:38 AM, Scott Anguish wrote:

    > Anyways, transitions don't exactly animate a Core Image transition
    > onto the content of a layer.

    Doesn't that defeat the whole purpose of transitions?

    > What are you trying to accomplish?

    I have a view that can take several states. I want to animate the
    view switching from one state to another using a CoreImage transition
    filter. I deleted the code a long time ago, since it wasn't working,
    but here's what I did.

    1. Created a layer for the view, but did not call -setWantsLayer: yet
    2. Created a CIFilter and set it up with the transition, and the
    before and after images
    3. Created a CATransition and set it to use the CIFilter
    4. Set the CATransition's delegate
    5. Added the CATransition to the view's layer
    6. Called -setWantsLayer: with YES

    If I read the documentation correctly, then the transition should
    start rendering in the view. But what actually happens is the view
    turns white, and no transition is drawn (but something is happening
    in the background, since the delegate did-start and did-finish
    methods are being called).

    If I use NSAnimation instead, swap out the view for a pseudo-image
    view, and draw each step into the view, then that works, but the
    frame rate is awful. I was hoping CoreAnimation would help me out
    here...

    Nick Zitzmann
    <http://www.chronosnet.com/>
  • On Oct 27, 2007, at 4:18 AM, Nick Zitzmann wrote:

    >
    > On Oct 27, 2007, at 1:38 AM, Scott Anguish wrote:
    >
    >> Anyways, transitions don't exactly animate a Core Image transition
    >> onto the content of a layer.
    >
    > Doesn't that defeat the whole purpose of transitions?
    >

    It was difficult to understand exactly what you were trying to
    accomplish from the original wording (i.e. were you just trying to
    apply the Core Image filter to the content directly)

    >> What are you trying to accomplish?
    >
    > I have a view that can take several states. I want to animate the
    > view switching from one state to another using a CoreImage
    > transition filter. I deleted the code a long time ago, since it
    > wasn't working, but here's what I did.
    >
    > 1. Created a layer for the view, but did not call -setWantsLayer: yet
    > 2. Created a CIFilter and set it up with the transition, and the
    > before and after images

    You shouldn't set the before and after images.  the inputImage and
    inputTargetImage and the outputImage all are set up automatically for
    you by Core Animation. The filter needs to support those keys though.
    Any additional keys you must set up. (Thinking about this more, I'll
    bet there is one more key that is required by CA to support it
    "inputTime"... Which is the thing that will animate over time.. I'll
    check with engineering.)

    >
    > 3. Created a CATransition and set it to use the CIFilter
    > 4. Set the CATransition's delegate
    > 5. Added the CATransition to the view's layer
    > 6. Called -setWantsLayer: with YES

    aside from the setting of the images, it sounds right.

    > If I read the documentation correctly, then the transition should
    > start rendering in the view. But what actually happens is the view
    > turns white, and no transition is drawn (but something is happening
    > in the background, since the delegate did-start and did-finish
    > methods are being called).

    Which CIFilter were you trying to use?  I'll play with it if you can
    tell me.

    But if you're switching between an old content image, and a new
    content image, the example I sent along will do that... and you can
    customize the
  • On Oct 27, 2007, at 12:56 PM, Scott Anguish wrote:

    > You shouldn't set the before and after images.  the inputImage and
    > inputTargetImage and the outputImage all are set up automatically
    > for you by Core Animation.

    How is it supposed to do that when it does not know the state of the
    view? Before I can do the transition, I need to get an
    NSBitmapImageRep of the view _before_ its state is changed, and then
    get a second image after changing the state of the view. This is in a
    view that does its own drawing independently of CoreAnimation. It's
    like plugging two images into a transition in the CoreImage Fun House
    app.

    > Which CIFilter were you trying to use?  I'll play with it if you can
    > tell me.

    I'm using CIPageCurlTransition. This one, in addition to requiring a
    source and target image, also needs a backside and shading image,
    which I have already done.

    Nick Zitzmann
    <http://www.chronosnet.com/>
  • On Oct 27, 2007, at 3:26 PM, Nick Zitzmann wrote:

    >
    > On Oct 27, 2007, at 12:56 PM, Scott Anguish wrote:
    >
    >> You shouldn't set the before and after images.  the inputImage and
    >> inputTargetImage and the outputImage all are set up automatically
    >> for you by Core Animation.
    >
    > How is it supposed to do that when it does not know the state of the
    > view? Before I can do the transition, I need to get an
    > NSBitmapImageRep of the view _before_ its state is changed, and then
    > get a second image after changing the state of the view. This is in
    > a view that does its own drawing independently of CoreAnimation.
    > It's like plugging two images into a transition in the CoreImage Fun
    > House app.

    Ah, you're using it independent of CA.. I believe that this may be the
    issue. Transitions are supported for certain types of view actions
    (added/removed) but I don't believe you can do it with content like
    this. I'm checking though.

    If you're in a straight CA environment the layer it can provide the
    state before and after by imaging it with the new value you've set the
    property to, and the original rendering.. and then animation between
    them taking the outputImage each time to display. I'm guessing if you
    provide this that the animation mechanism will override the values you
    set.
  • On Oct 27, 2007, at 5:51 PM, Scott Anguish wrote:

    > If you're in a straight CA environment the layer it can provide the
    > state before and after by imaging it with the new value you've set
    > the property to, and the original rendering..

    Oh, so that's what it's for... I was hoping CATransition would work
    on traditional views, but I guess I'm going to have to stick to
    NSAnimation...

    Nick Zitzmann
    <http://www.chronosnet.com/>
  • On Oct 27, 2007, at 11:44 PM, Nick Zitzmann wrote:

    >
    > On Oct 27, 2007, at 5:51 PM, Scott Anguish wrote:
    >
    >> If you're in a straight CA environment the layer it can provide the
    >> state before and after by imaging it with the new value you've set
    >> the property to, and the original rendering..
    >
    > Oh, so that's what it's for... I was hoping CATransition would work
    > on traditional views, but I guess I'm going to have to stick to
    > NSAnimation...

    Well, it does when you're adding/removing views from the parent view.
    There are two keys you can use to add transitions that will be used
    then.

    If your view/control only has a single thing in it you could set up
    the view as a layer-hosting view, transition your drawing code from
    drawRect: to one of the layer delegate methods, and leave all the
    mouse/event handling in the view.. you'd get the CA features like
    transitions and implicit and explicit animations..
previous month october 2007 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today