CALayer Resize Slower

I'm having some performance issues with some code that I wrote to resize CALayer using touch. It works great, but the animation is far from fast enough and lags behind the point of touch.

CGPoint startPoint; CALayer *select; - (CGRect)rectPoint:(CGPoint)p1 toPoint:(CGPoint)p2 { CGFloat x, y, w, h; if (p1.x < p2.x) { x = p1.x; w = p2.x - p1.x; } else { x = p2.x; w = p1.x - p2.x; } if (p1.y < p2.y) { y = p1.y; h = p2.y - p1.y; } else { y = p2.y; h = p1.y - p2.y; } return CGRectMake(x, y, w, h); } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *t1 = [[[event allTouches]allObjects]objectAtIndex:0]; CGPoint loc = [t1 locationInView:self]; startPoint = loc; lastPoint = CGPointMake(loc.x + 5, loc.y + 5); select = [CALayer layer]; select.backgroundColor = [[UIColor blackColor]CGColor]; select.frame = CGRectMake(startPoint.x, startPoint.y, 5, 5); [self.layer addSublayer:select]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *t1 = [[[event allTouches]allObjects]objectAtIndex:0]; CGPoint loc = [t1 locationInView:self]; select.bounds = [self rectPoint:startPoint toPoint:loc]; } 

Is there a better way to achieve this?

+6
source share
2 answers

The delay is that you change the bounds property of the layer, which is the animating property.

With CALayers (CA stands for basic animation ...), any change in the animation property will be animated by default. This is called implicit animation. By default, an animation takes 0.25 seconds, so if you update it often, say, when processing touches, it will add up and cause a visible lag.

To prevent this, you must declare an animation transaction, disable implicit animations, and then change the properties:

 [CATransaction begin]; [CATransaction setDisableActions:YES]; layer.bounds = whatever; [CATransaction commit]; 
+24
source

Accepted answer in Swift 3/4:

 CATransaction.begin() CATransaction.setDisableActions(true) layer.bounds = whatever CATransaction.commit() 

It should be noted that this also applies to .frame properties, for example, when you resize AVPlayerLayer:

 override func layoutSubviews() { CATransaction.begin() CATransaction.setDisableActions(true) playerLayer.frame = self.bounds CATransaction.commit() } 
+1
source

Source: https://habr.com/ru/post/922545/


All Articles