15.2 離屏渲染

2018-02-24 15:07 更新

離屏渲染

????當(dāng)圖層屬性的混合體被指定為在未預(yù)合成之前不能直接在屏幕中繪制時(shí),屏幕外渲染就被喚起了。屏幕外渲染并不意味著軟件繪制,但是它意味著圖層必須在被顯示之前在一個(gè)屏幕外上下文中被渲染(不論CPU還是GPU)。圖層的以下屬性將會(huì)觸發(fā)屏幕外繪制:

  • 圓角(當(dāng)和maskToBounds一起使用時(shí))
  • 圖層蒙板
  • 陰影

????屏幕外渲染和我們啟用光柵化時(shí)相似,除了它并沒(méi)有像光柵化圖層那么消耗大,子圖層并沒(méi)有被影響到,而且結(jié)果也沒(méi)有被緩存,所以不會(huì)有長(zhǎng)期的內(nèi)存占用。但是,如果太多圖層在屏幕外渲染依然會(huì)影響到性能。

????有時(shí)候我們可以把那些需要屏幕外繪制的圖層開(kāi)啟光柵化以作為一個(gè)優(yōu)化方式,前提是這些圖層并不會(huì)被頻繁地重繪。

????對(duì)于那些需要?jiǎng)赢?huà)而且要在屏幕外渲染的圖層來(lái)說(shuō),你可以用CAShapeLayer,contentsCenter或者shadowPath來(lái)獲得同樣的表現(xiàn)而且較少地影響到性能。

CAShapeLayer

????cornerRadiusmaskToBounds獨(dú)立作用的時(shí)候都不會(huì)有太大的性能問(wèn)題,但是當(dāng)他倆結(jié)合在一起,就觸發(fā)了屏幕外渲染。有時(shí)候你想顯示圓角并沿著圖層裁切子圖層的時(shí)候,你可能會(huì)發(fā)現(xiàn)你并不需要沿著圓角裁切,這個(gè)情況下用CAShapeLayer就可以避免這個(gè)問(wèn)題了。

????你想要的只是圓角且沿著矩形邊界裁切,同時(shí)還不希望引起性能問(wèn)題。其實(shí)你可以用現(xiàn)成的UIBezierPath的構(gòu)造器+bezierPathWithRoundedRect:cornerRadius:(見(jiàn)清單15.1).這樣做并不會(huì)比直接用cornerRadius更快,但是它避免了性能問(wèn)題。

清單15.1 用CAShapeLayer畫(huà)一個(gè)圓角矩形

#import "ViewController.h"
#import 

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIView *layerView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    //create shape layer
    CAShapeLayer *blueLayer = [CAShapeLayer layer];
    blueLayer.frame = CGRectMake(50, 50, 100, 100);
    blueLayer.fillColor = [UIColor blueColor].CGColor;
    blueLayer.path = [UIBezierPath bezierPathWithRoundedRect:
    CGRectMake(0, 0, 100, 100) cornerRadius:20].CGPath;
    ?
    //add it to our view
    [self.layerView.layer addSublayer:blueLayer];
}
@end

可伸縮圖片

????另一個(gè)創(chuàng)建圓角矩形的方法就是用一個(gè)圓形內(nèi)容圖片并結(jié)合第二章『寄宿圖』提到的contensCenter屬性去創(chuàng)建一個(gè)可伸縮圖片(見(jiàn)清單15.2).理論上來(lái)說(shuō),這個(gè)應(yīng)該比用CAShapeLayer要快,因?yàn)橐粋€(gè)可拉伸圖片只需要18個(gè)三角形(一個(gè)圖片是由一個(gè)3*3網(wǎng)格渲染而成),然而,許多都需要渲染成一個(gè)順滑的曲線。在實(shí)際應(yīng)用上,二者并沒(méi)有太大的區(qū)別。

清單15.2 用可伸縮圖片繪制圓角矩形

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    //create layer
    CALayer *blueLayer = [CALayer layer];
    blueLayer.frame = CGRectMake(50, 50, 100, 100);
    blueLayer.contentsCenter = CGRectMake(0.5, 0.5, 0.0, 0.0);
    blueLayer.contentsScale = [UIScreen mainScreen].scale;
    blueLayer.contents = (__bridge id)[UIImage imageNamed:@"Circle.png"].CGImage;
    //add it to our view
    [self.layerView.layer addSublayer:blueLayer];
}
@end

????使用可伸縮圖片的優(yōu)勢(shì)在于它可以繪制成任意邊框效果而不需要額外的性能消耗。舉個(gè)例子,可伸縮圖片甚至還可以顯示出矩形陰影的效果。

shadowPath

????在第2章我們有提到shadowPath屬性。如果圖層是一個(gè)簡(jiǎn)單幾何圖形如矩形或者圓角矩形(假設(shè)不包含任何透明部分或者子圖層),創(chuàng)建出一個(gè)對(duì)應(yīng)形狀的陰影路徑就比較容易,而且Core Animation繪制這個(gè)陰影也相當(dāng)簡(jiǎn)單,避免了屏幕外的圖層部分的預(yù)排版需求。這對(duì)性能來(lái)說(shuō)很有幫助。

????如果你的圖層是一個(gè)更復(fù)雜的圖形,生成正確的陰影路徑可能就比較難了,這樣子的話你可以考慮用繪圖軟件預(yù)先生成一個(gè)陰影背景圖。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)