2012-08-10 25 views
6

Tôi đang gặp một số vấn đề về hiệu suất với một số mã mà tôi đã viết để thay đổi kích thước một CALayer bằng cách sử dụng cảm ứng. Nó hoạt động tốt nhưng hoạt hình là xa đủ linh hoạt và chậm phía sau vị trí cảm ứng.CALayer Resize là chậm

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

Có cách nào tốt hơn để đạt được điều này không?

Trả lời

24

Độ trễ là do bạn đang thay đổi thuộc tính bounds của lớp, đây là thuộc tính có thể hoạt ảnh.

Với CALayers (CA là viết tắt của hoạt ảnh lõi ...), bất kỳ thay đổi nào đối với thuộc tính có thể hoạt ảnh sẽ được làm động theo mặc định. Đây được gọi là hoạt ảnh ngầm. Hoạt ảnh mặc định mất 0,25 giây, vì vậy nếu bạn đang cập nhật thường xuyên, nói trong quá trình xử lý chạm, điều này sẽ tăng lên và gây ra độ trễ hiển thị.

Để tránh điều này, bạn phải khai báo một giao dịch hoạt hình, tắt hình ảnh động ngầm, sau đó thay đổi các thuộc tính:

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

sẽ đưa tôi ít nhất một ngày để tìm ra điều đó một cách độc lập, nhờ stack + jrturton. –

1

câu trả lời chấp nhận trong Swift 3/4:

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

Đáng nói rằng điều này cũng áp dụng cho các thuộc tính .frame, ví dụ: khi bạn đang định lại kích thước AVPlayerLayer:

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