CALayer/CABasicAnimation and HS: New behavior I don't understand
CALayer/CABasicAnimation and HS: New behavior I don't understand
- Subject: CALayer/CABasicAnimation and HS: New behavior I don't understand
- From: "email@hidden" <email@hidden>
- Date: Wed, 27 Sep 2017 15:48:51 -0400
I have a NSImageView subclass which provides an audio waveform, and which
creates a CALayer that animates a wiper that scrolls across the waveform as a
track is playing using the ‘position’ params (to, from) along with the
(remaining) track duration.
Until 10.13, I created the CALayer for the wiper in the imageView’s
awakeFromNib method - as it would always have the same size and contents, and
just needed to have its fromValue, toValue, and duration changed for either a
new track, or a new start point in a track if the user clicked within the
waveform.
This worked perfectly. To reposition the wiper, I’d remove the existing
animation and add a new one to the wiper layer with updated from and duration
values. (the ‘to’ value would always point to the end of the track).
But in 10.13 this no longer works. I find I have to create a new layer each
time I need to reposition the wiper. Somehow it seems as though the layer
property in my view (strong, nonatomic) no longer survives more than a single
use.
All works normally now, by instantiating the CALayer each time I want to change
on of its params, but I don’t understand what has changed in 10.13 to change
the behavior. It took a bit of trial and error to find the fix.
I’m sure I was doing something wrong in the versions that ran perfectly under
10.9 - 10.12, but I cannot find any documentation that explains why it would
not work under 10.13, and it sort of bothers me that I now have to remove the
existing CALayer (with the animation) and create a new CALayer just to
reposition the wiper.
Here’s the code that used to be in awakeFromNib: to create a layer that lasted
for the entire app run:
/*
CGPoint zeroPt = CGPointMake(0,0);
self.layer.anchorPoint = zeroPt;
self.wiperLayer = [CALayer layer];
[_wiperLayer setFrame:NSMakeRect(0, 0, 1, 61)]; // wiper is fixed
width/height
_wiperLayer.bounds = NSMakeRect(0, 0, 1, 61);
_wiperLayer.contents = [NSImage imageNamed:@"wiper.png”]; // just a red
vertical line
_wiperLayer.anchorPoint = zeroPt;
[[self layer] addSublayer:_wiperLayer];
_wiperLayer.position = zeroPt;
*/
In order to see the wiper in 10.13, I had to move this code to the reposition
method, like so:
//-----------------------------------------------------------------------
- (void)startWiperAtPct:(float)pct
//-----------------------------------------------------------------------
{
CGPoint zeroPt = CGPointMake(0,0);
self.layer.anchorPoint = zeroPt;
if( _wiperLayer ){ // we have to add a new one to make it work, so have
to get rid of the last one
[_wiperLayer removeFromSuperlayer];
}
self.wiperLayer = [CALayer layer];
[_wiperLayer setFrame:NSMakeRect(0, 0, 1, 61)];
_wiperLayer.bounds = NSMakeRect(0, 0, 1, 61);
_wiperLayer.contents = [NSImage imageNamed:@"wiper.png"];
_wiperLayer.anchorPoint = zeroPt;
[[self layer] addSublayer:_wiperLayer];
_wiperLayer.position = zeroPt;
CAAnimation* animation = [self.wiperLayer animationForKey:@"position"];
if( animation && pct){
DLOG(@"have animation: wiper resuming");
[self resumeWiper];
}
else{
if( animation )
[_wiperLayer removeAllAnimations];
DLOG(@"wiper starting at pct: %f", pct);
NSInteger startPixel = self.bounds.size.width * pct;
CABasicAnimation* ba = [CABasicAnimation
animationWithKeyPath:@"position"];
ba.fromValue = [NSValue valueWithPoint:CGPointMake(startPixel
,0)];
ba.toValue = [NSValue
valueWithPoint:CGPointMake(self.bounds.size.width,0)];
ba.duration = _currentDuration - (pct * _currentDuration);
DLOG(@"Animation duration: %f", _currentDuration);
[_wiperLayer addAnimation:ba forKey:@"position"];
_wiperLayer.speed = 1.0;
}
}
There are other methods for pausing and resuming, but they work the same in
10.13.
Any light on this would be most welcome, as I hate not knowing why something
stopped working!
Rob
_______________________________________________
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