• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Problem with CATransaction
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Problem with CATransaction


  • Subject: Problem with CATransaction
  • From: Gabriel Zachmann <email@hidden>
  • Date: Sat, 06 Oct 2012 00:15:39 +0200

Dear all,

I have a problem with CA with my screensaver when it runs under Mountain Lion.

My screensaver displays images, a new one every minute. I have used Core Animation to achieve a blending effect
when the image gets replaced by a new one.
Everything else seems to work fine, but the blending effect that I used to get is gone.

I have already googled and it seems to me that others have experienced the same problem, but I am unsure as to how to go about to fix the problem.

Here is my code in a bit more detail.

I define a number of layers in my class:

@interface ArtSaverView : ScreenSaverView <NSTextViewDelegate>
{
[...]
	CALayer * mainLayer_;
	CALayer * currentLayer_;
	CALayer * textLayer_;					// holds the image name / error message at the bottom
}


Then I set up some initial layers:

- (id) initWithFrame: (NSRect) frameRect isPreview: (BOOL) preview
{
[...]
    // create some layers
    // make the view layer-hosting and become the delegate for the root layer
    mainLayer_ = [CALayer layer];
    mainLayer_.zPosition = 0.0;
    mainLayer_.delegate = self;
    [mainLayer_ setNeedsDisplay];
    // causes the layer content to be drawn in -drawRect:
    [self setLayer: mainLayer_];
    self.wantsLayer = YES;
    [self setNeedsDisplay: YES];

    // insert a dummy layer as a placeholder for the image layer later
    currentLayer_ = [CALayer layer];
    [mainLayer_ addSublayer: currentLayer_];

    textLayer_ = [CALayer layer];
    textLayer_.zPosition = 0.0;
    textLayer_.bounds = NSRectToCGRect( drawRect_ );	// Warning: if bounds==nil or the empty rectangle, then the delegate's drawLayer: won't get called!
    TextLayerDelegate * textlayer_delegate = [[TextLayerDelegate alloc] initWith: self];
    CFRetain( textlayer_delegate );      // otherwise, it seems, the textlayer_delegate gets collected away by the GC ..
    textLayer_.delegate = textlayer_delegate;
    textLayer_.position = CGPointMake( 0,0 );
    textLayer_.anchorPoint = CGPointMake( 0, 0 );
    textLayer_.opacity = 1.0;
    [textLayer_ setNeedsDisplay];
    [mainLayer_ addSublayer: textLayer_ ];
[...]
}


The idea is that, during runtime, the 'currentLayer' gets replaced by a different layer from time to time,
and letting Core Animation do the fade-out/fade-in effect of the two layers, resp.

I am doing that in the screen savers "workproc":

- (void) animateOneFrame
{
[...]
    // create new layer that centeres the new image
    CALayer * newlayer;
    newlayer = [self makeImageLayer: imageRef withOrientation: img_orientation];
    newlayer.contentsGravity = kCAGravityResizeAspectFill;

    // swap the old and the new layer
    [CATransaction begin];
    // causes cross-dissolve animation
    [CATransaction setAnimationDuration: fading_duration];
    [mainLayer_ replaceSublayer: currentLayer_ with: newlayer];
    currentLayer_ = newlayer;
    [CATransaction commit];
}


A new layer, containing an image, is created with this sub-routine:

- (CALayer *) makeImageLayer: (CGImageRef) img withOrientation: (int) orientation
{
    // create new layer containing the image
    CALayer * imgLayer		= [CALayer layer];
    imgLayer.contents		= (id) img;
    imgLayer.contentsGravity	= kCAGravityResizeAspect; // kCAGravityCenter;
    imgLayer.delegate		= nil;
    imgLayer.opacity		= 1.0;
    imgLayer.position		= CGPointMake( drawRect_.size.width/2.0, drawRect_.size.height/2.0 );
    imgLayer.anchorPoint	= CGPointMake( 0.5, 0.5 );
    imgLayer.zPosition		= -1.0;         // makes the image appear behind the text
    imgLayer.bounds 		= NSRectToCGRect( drawRect_ );

    CGImageRelease( img );

    return imgLayer;
}




Unfortunately, I am not very deep into Core Animations.


So, my question is: is there an easy way to make the blending effect reappear, without rewriting too much of my code?
In my current code, the blending is done by just a few lines of code, and I would be happy if the new solution
could be as concise ;-)


Thanks a lot in advance.


Best regards,
Gabriel.


_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Prev by Date: NSTableView how to sort rows after modify datasource array
  • Next by Date: Problem with CATransaction
  • Previous by thread: Re: NSTableView how to sort rows after modify datasource array
  • Next by thread: Problem with CATransaction
  • Index(es):
    • Date
    • Thread