2012-04-12 30 views
35

QuartzCore .layer.shadow's suck up performance. Chúng dường như cần phải được trả lại mỗi khi có điều gì đó thay đổi, làm cho mọi thứ bị trễ.Cách nhanh nhất để tạo bóng trên iOS?

Gradient bản đồ (đối với bóng 1 chiều) - trông không đúng. nếu gradient của bạn đi từ 0,3 alpha đến 0, nó có một số hiệu ứng kỳ lạ, nơi bạn có thể 'thấy' nó dừng lại. Nó không có vẻ đẹp hay tự nhiên. Có lẽ nó không được phối màu, nhưng tôi chắc chắn rằng tôi đã nghe các gradient đồ họa lõi. Thật kỳ lạ, tôi không biết.

Bóng đồ họa - mất một lúc để hiển thị khi bạn đặt chúng, nhưng nếu không thì hiệu suất tuyệt vời. Nó chỉ là thứ hai bạn đang chờ đợi một cái nhìn xuất hiện bởi vì nó đã làm cho nó bóng tối đầu tiên, đó là vấn đề.

Vì vậy, tôi phải thiếu điều gì đó. Có phương pháp nào khác có vẻ đúng và có tốc độ nhanh trong cả thời gian hiển thị và hiệu suất không?

Trả lời

100

Thêm shadowPath sẽ cung cấp cho bạn hiệu suất rất lớn. Ví dụ sau đây giả sử bạn chỉ muốn cái bóng trên các mặt của quan điểm của bạn

CGPathRef path = [UIBezierPath bezierPathWithRect:view.bounds].CGPath; 
[view.layer setShadowPath:path]; 

EDIT: Mở mặc định một CALayer vẽ một cái bóng trong hình ảnh động, các mã sau đây cho phép bạn cache bóng như một bitmap và tái sử dụng nó thay vì vẽ lại nó:

self.view.layer.shouldRasterize = YES; 
// Don't forget the rasterization scale 
// I spent days trying to figure out why retina display assets weren't working as expected 
self.view.layer.rasterizationScale = [UIScreen mainScreen].scale; 
+2

Awesome! shouldRasterize tài sản thực hiện các trick. Cảm ơn bạn! – DZenBot

+1

rasterizationScale đã đuổi tôi ra ngoài một lúc! Bạn sẽ tưởng tượng nó sẽ mặc định dựa trên quy mô màn hình, nhưng không. : -/ – Dermot

+0

Tôi có một phần PNG trong suốt với các cạnh lởm chởm mà tôi phải tạo hiệu ứng động (với bóng, dĩ nhiên). Đó là 2/3 kích thước màn hình, vì vậy khá một vài pixel. Giải pháp này vẫn hoạt động hoàn hảo. :) – toblerpwn

8

tôi thường thấy những người sử dụng layer HUGE hiệu suất tác động xem để tạo ra một góc tròn hoặc DropShadow. Một cái gì đó như thế này:

[v.layer setCornerRadius:30.0f]; 
[v.layer setBorderColor:[UIColor lightGrayColor].CGColor]; 
[v.layer setBorderWidth:1.5f]; 
[v.layer setShadowColor:[UIColor blackColor].CGColor]; 
[v.layer setShadowOpacity:0.8]; 
[v.layer setShadowRadius:3.0]; 
[v.layer setShadowOffset:CGSizeMake(2.0, 2.0)]; 
..... 

này có tác động hiệu quả HUGE, đặc biệt là với cái bóng. Đặt các lượt xem như thế này trong một UITableView (hoặc thực tế vật chất di chuyển) sẽ tạo ra trải nghiệm cuộn android-ish, bạn không muốn điều đó. Nếu bạn cần tạo hiệu ứng động hoặc di chuyển chế độ xem, tránh tạo các góc được làm tròn hoặc đổ bóng như thế này bằng bất kỳ cách nào!

Gặp Lõi đồ họa
tôi đã tạo ra một phân lớp UIView đơn giản để cho bạn thấy làm thế nào để đạt được kết quả tương tự theo một cách hơi khác nhau. Nó sử dụng đồ họa cốt lõi để vẽ chế độ xem và ngược lại với mã ở trên, nó không ảnh hưởng đến hiệu suất.

Dưới đây là đoạn code vẽ:

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef ref = UIGraphicsGetCurrentContext(); 

    /* We can only draw inside our view, so we need to inset the actual 'rounded content' */ 
    CGRect contentRect = CGRectInset(rect, _shadowRadius, _shadowRadius); 

    /* Create the rounded path and fill it */ 
    UIBezierPath *roundedPath = [UIBezierPath bezierPathWithRoundedRect:contentRect cornerRadius:_cornerRadius]; 
    CGContextSetFillColorWithColor(ref, _fillColor.CGColor); 
    CGContextSetShadowWithColor(ref, CGSizeMake(0.0, 0.0), _shadowRadius, _shadowColor.CGColor); 
    [roundedPath fill]; 

    /* Draw a subtle white line at the top of the view */ 
    [roundedPath addClip]; 
    CGContextSetStrokeColorWithColor(ref, [UIColor colorWithWhite:1.0 alpha:0.6].CGColor); 
    CGContextSetBlendMode(ref, kCGBlendModeOverlay); 

    CGContextMoveToPoint(ref, CGRectGetMinX(contentRect), CGRectGetMinY(contentRect)+0.5); 
    CGContextAddLineToPoint(ref, CGRectGetMaxX(contentRect), CGRectGetMinY(contentRect)+0.5); 
    CGContextStrokePath(ref); 
} 

Xem blog này: http://damir.me/rounded-uiview-with-shadow-the-right-way

+0

Liên kết tới kho lưu trữ git trong blog này dường như không hoạt động nữa. Làm thế nào tôi nên sử dụng điều này trên một UICollectionViewCell? – trdavidson

+1

Thêm bản vẽ bên trên vào lớp con của bạn của UICollectionViewCell @trdavidson –

+0

tuyệt vời! cảm ơn - điều đó đã thực hiện thủ thuật – trdavidson

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