2012-08-10 5 views
6

터치를 사용하여 CALayer의 크기를 조정하기 위해 작성한 일부 코드에 성능 문제가 있습니다. 괜찮 았지만 애니메이션은 너무 부드럽고 터치 위치보다 뒤떨어져 있습니다.CALayer 크기가 느립니다.

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]; 
} 

더 좋은 방법이 있나요?

답변

24

지연은 애니메이션 가능한 속성 인 레이어의 bounds 속성을 변경하기 때문에 발생합니다.

CALayers (CA는 핵심 애니메이션을 의미합니다 ...)를 사용하면 애니메이션 가능한 속성의 모든 변경 사항이 기본적으로 애니메이션으로 표시됩니다. 이를 암시 적 애니메이션이라고합니다. 기본 애니메이션에는 0.25 초가 걸리므로 터치를 처리하는 중 자주 업데이트하면이를 추가하여 가시적 인 지연을 유발합니다.

것은이를 방지하기 위해, 당신은, 애니메이션 트랜잭션을 선언 암시 애니메이션을 해제해야합니다, 다음 속성을 변경 :

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

은 독립적으로 그걸 알아내는 데 적어도 하루는 걸렸을 것입니다, 스택 + jrturton에게 감사드립니다. –

1

허용 대답을 스위프트 3/4 : 언급 할

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

가치 AVPlayerLayer의 크기를 조정할 때와 같이 .frame 속성에도 적용됩니다.

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