2012-02-21 36 views
5

Tôi đang tạo đối tượng NSView tùy chỉnh có một số nội dung thay đổi thường xuyên và một số thay đổi thường xuyên hơn nhiều. Vì nó sẽ bật ra, các bộ phận thay đổi ít thường xuyên mất nhiều thời gian nhất để vẽ. Những gì tôi muốn làm là làm cho hai phần này trong các lớp khác nhau, để tôi có thể cập nhật một phần hoặc riêng biệt khác, do đó giúp người dùng của tôi có giao diện người dùng chậm chạp.Tôi có thể sử dụng CALayer để tăng tốc độ hiển thị xem không?

Làm cách nào để tôi thực hiện việc này? Tôi đã không tìm thấy nhiều hướng dẫn tốt về loại điều này, và không ai nói về việc vẽ NSBezierPaths trên một CALayer. Ý tưởng bất cứ ai?

Trả lời

4

Linh cảm của bạn là đúng, đây thực sự là một cách tuyệt vời để tối ưu hóa bản vẽ. Tôi đã tự làm nó ở nơi tôi có một số nền tĩnh lớn mà tôi muốn tránh vẽ lại khi các yếu tố di chuyển lên trên.

Tất cả những gì bạn cần làm là thêm CALayer đối tượng cho từng mục nội dung trong chế độ xem của bạn. Để vẽ các lớp, bạn nên đặt chế độ xem làm đại biểu cho từng lớp và sau đó triển khai phương thức drawLayer:inContext:.

Trong phương pháp mà bạn chỉ cần vẽ các nội dung của mỗi lớp:

- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx 
{ 
    if(layer == yourBackgroundLayer) 
    { 
     //draw your background content in the context 
     //you can either use Quartz drawing directly in the CGContextRef, 
     //or if you want to use the Cocoa drawing objects you can do this: 
     NSGraphicsContext* drawingContext = [NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:YES]; 
     NSGraphicsContext* previousContext = [NSGraphicsContext currentContext]; 
     [NSGraphicsContext setCurrentContext:drawingContext]; 
     [NSGraphicsContext saveGraphicsState]; 
     //draw some stuff with NSBezierPath etc 
     [NSGraphicsContext restoreGraphicsState]; 
     [NSGraphicsContext setCurrentContext:previousContext]; 
    } 
    else if (layer == someOtherLayer) 
    { 
     //draw other layer 
    } 
    //etc etc 
} 

Khi bạn muốn cập nhật nội dung của một trong các lớp, chỉ cần gọi [yourLayer setNeedsDisplay]. Điều này sau đó sẽ gọi phương thức ủy nhiệm ở trên để cung cấp nội dung cập nhật của lớp.

Lưu ý rằng theo mặc định, khi bạn thay đổi nội dung lớp, Core Animation cung cấp một chuyển đổi mờ dần đẹp cho nội dung mới. Tuy nhiên, nếu bạn đang xử lý bản vẽ, có thể bạn không muốn điều này, vì vậy để tránh làm mờ hoạt ảnh mặc định khi nội dung của lớp thay đổi, bạn cũng phải triển khai phương thức ủy quyền actionForLayer:forKey: và ngăn hoạt ảnh bằng cách trả về hành động rỗng:

- (id<CAAction>)actionForLayer:(CALayer*)layer forKey:(NSString*)key 
{ 
    if(layer == someLayer) 
    { 
     //we don't want to animate new content in and out 
     if([key isEqualToString:@"contents"]) 
     { 
      return (id<CAAction>)[NSNull null]; 
     } 
    } 
    //the default action for everything else 
    return nil; 
} 
+0

Cảm ơn, điều này rất hữu ích. Tuy nhiên, tôi đang gặp khó khăn trong việc đưa phương thức ủy nhiệm để kích hoạt. Tôi thiết lập quan điểm của tôi với tư cách là người đại diện và tôi đang thêm các lớp làm lớp con của lớp gốc, và tôi đang gọi 'setNeedsDisplay' nhưng' drawLayer: inContext' không bao giờ được gọi. Ý tưởng nào? – mtmurdock

+0

Bạn có thể đăng mã của mình không? Điều này sẽ làm việc. –

+0

Tôi cũng ghi đè 'drawRect:' có thể khiến nó không gọi hàm kia không? – mtmurdock

Các vấn đề liên quan