IOS Layer的"自動布局"
前言:今天在stackoverflow上給一個外國友人回答問題的時候,遇到了Layer的自動布局的問題。這裡寫出來,分享給需要的人。
Layer支援autolayout嗎?
ios 的CALayer到目前為止不支援AutoLayout也不支援autoresizingMask。
舉個例子
如果,要繪製一個漸層的顏色,作為背景色。定義一個配置函數
-(void)setupCAGradientLayer:(CAGradientLayer *)gradient{ UIColor *colorOne = [UIColor colorWithRed:(120/255.0) green:(135/255.0) blue:(150/255.0) alpha:1.0]; UIColor *colorTwo = [UIColor colorWithRed:(57/255.0) green:(79/255.0) blue:(96/255.0) alpha:1.0]; NSArray *colors = [NSArray arrayWithObjects:(id)colorOne.CGColor, colorTwo.CGColor, nil]; NSNumber *stopOne = [NSNumber numberWithFloat:0.0]; NSNumber *stopTwo = [NSNumber numberWithFloat:1.0]; NSArray *locations = [NSArray arrayWithObjects:stopOne, stopTwo, nil]; gradient.colors = colors; gradient.locations = locations;}
不使用圖片作為背景的話,一種直接的方式就是使用Layer進行繪製
很簡單的繪製
#import ViewController.h@interface ViewController ()@property (strong,nonatomic) CAGradientLayer * gradient;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; self.gradient = [CAGradientLayer layer]; [self setupCAGradientLayer:self.gradient]; self.gradient.frame = self.view.frame; [self.view.layer addSublayer:self.gradient];}
但是,橫屏後就發現不對了
粗糙的解決方案
最直觀的解決方案就是,在進行view的bounds改變的時候,進行layer的大小調整。
代碼很簡單,由於在view的bounds改變的時候,在對應的controller會調用viewDidLayoutSubviews
所以,在上面的viewController中加入如下代碼,
-(void)viewDidLayoutSubviews{ [super viewDidLayoutSubviews]; self.gradient.frame = self.view.bounds;}
則橫屏正常
但是,我們都知道,在橫豎屏切換的時候,IOS會自動產生一個動畫,如果用粗糙的解決方案,只是在動畫結束後改變了frame,動畫的過程中仍然能夠看淡空白
較好的解決方案
由於IOS對view的支援較好,不管是使用auto layout,還是autoresizingmask,都很方便。所以,一種比較好的解決方案就是使用view來處理。
把layer綁定到view
定義一個view,把他的layer的class設定為CAGradientClass
#import @interface BackgrundView : UIView@end
#import BackgrundView.h@interface BackgrundView()@end@implementation BackgrundView+(Class)layerClass{ return [CAGradientLayer class];}@end
然後,使用這個view,設定autoresizingmask
#import ViewController.h#import BackgrundView.h@interface ViewController ()@property BackgrundView * backgroundview;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; self.backgroundview = [[BackgrundView alloc] initWithFrame:self.view.frame]; self.backgroundview.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; [self.view addSubview:self.backgroundview]; [self setupCAGradientLayer:(CAGradientLayer*)self.backgroundview.layer]; }@end
再看看切換的動畫(產生的gif有點浮水印,諒解)