• 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: Mon, 08 Oct 2012 21:41:41 +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: Problem with CATransaction
  • Next by Date: Re: Embedding resources in Static Cocoa Library
  • Previous by thread: Problem with CATransaction
  • Next by thread: Hierarchy Posters
  • Index(es):
    • Date
    • Thread