漸變的核心幾個部分:git
1.狀態欄的變色:github
添加一個狀態欄屬性BooL變量app
@property(nonatomic,assign)BOOL lightStatusBar;//狀態欄的顏色控制atom
咱們能夠在ViewController裏面重寫系統的這個方法來動態設置狀態欄顏色(白色/黑色):
-(UIStatusBarStyle)preferredStatusBarStyle{
return self.lightStatusBar ? UIStatusBarStyleLightContent : UIStatusBarStyleDefault;
}
若是須要主動的觸發上面的方法改變狀態欄顏色,咱們能夠直接調用這個方法 [self setNeedsStatusBarAppearanceUpdate];在ViewController寫完上面兩步,滑動導航欄會發現好像沒什麼卵用,狀態欄顏色沒變啊!代理
由於咱們須要在UINavigationController裏面重寫下面這個方法-(UIViewController *)childViewControllerForStatusBarStyle;爲何要重寫這個?這個方法默認返回值是nil,也就是當咱們調用setNeedsStatusBarAppearanceUpdate的時候,系統會調用container(容器控制器)的preferredStatusBarStyle這個方法(app.window.rootViewController的preferred的方法,通常咱們用UINavigationController或者UITabBarController來作container),也就是根本不會調用子控制器(咱們所看到的UIViewcontroller)的preferredStatusBarStyle方法。這個時候- (UIViewController *)childViewControllerForStatusBarStyle:就派上用場了
給UINavigationController添加一個分類添加以下orm
重寫這個方法,系統會調用container(容器控制器)就會返回當前的UIViewController,從而UIViewController裏面重寫的方法就會調用,狀態欄的顏色就會相應改變。以上就是狀態欄的變色出處理blog
2.導航欄的漸變繼承
先作一下基礎的設置:遞歸
1.禁止系統對繼承Scrollview的控件的自動偏移圖片
2.隱藏導航欄底部的線條,不處理的話導航欄透明時會明顯看到一條黑線,辣眼睛。寫個遞歸找到線條
調用上面方法找到線條圖片,隱藏便可。
UIImageView *iamgeV = [self findBackLineImageV:self.navigationController.navigationBar];
iamgeV.hidden = YES;
當咱們滑動的時候會觸發代理方法(必需要是繼承Scrollview的控件設置代理纔會觸發):
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
}
在上面的方法咱們主要作如下幾件事情(把上面方法內容拆分說明一下):
1.滑動偏移量獲取,經過滑動偏移量計算導航欄的透明度。
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
offset = scrollView.contentOffset.y;
UIColor *color = [UIColor colorWithWhite:1.0 alpha:offset/self.offsetChange];
[self.navigationController.navigationBar setBackgroundImage:[self imageWithColor:color] forBarMetrics:UIBarMetricsDefault];
}
//繪製一張圖片
- (UIImage *)imageWithColor:(UIColor *)color {
CGSize size = CGSizeMake(1, 1);
if (!color || size.width <= 0 || size.height <= 0) return nil;
CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
2.滑動偏移量到設置的偏移量臨界值時的處理(切換back圖片,標題文字顏色,狀態欄的bool值等)。
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
//導航欄漸變處理
if (offset >= _offsetChange) {
[self setBackNavNomal];
}else{
[self setBackNavDiaphanous];
}
}
//不透明導航欄
-(void)setBackNavNomal
{
self.navigationController.navigationBar.titleTextAttributes=@{NSForegroundColorAttributeName: self.notLucencyTitleColor,NSFontAttributeName:[UIFont systemFontOfSize:18]};
[self setNavigationLeftItemWithImageName:@"more_dark"];
[self.rightBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
self.lightStatusBar = NO;
}
//透明導航欄
-(void)setBackNavDiaphanous
{
self.navigationController.navigationBar.titleTextAttributes= @{NSForegroundColorAttributeName: self.lucencyTitleColor,NSFontAttributeName:[UIFont systemFontOfSize:18]};
[self setNavigationLeftItemWithImageName:@"navigationBack"];
[self.rightBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
self.lightStatusBar = YES;
}
3.當tableview有組頭而且組頭要懸浮在導航欄下面,須要作的處理。
self.contentHeight爲tableview的佔屏大小,若是contentSize不用滑動就能顯示完整,contentInset就不要修改,否則向上滑會有點bug。
self.offsetChange參數:沒組頭通常默認64就行,有組頭則爲組頭到頂部的距離
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (self.tableView.contentSize.height >= self.contentHeight) {
//導航欄漸變處理
if (offset >= self.offsetChange) {
self.tableView.contentInset = UIEdgeInsetsMake(KStatusBarAndNavigationBarHeight, 0, 0, 0);
}else{
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
}
}
}
總體-(void)scrollViewDidScroll:(UIScrollView *)scrollView 方法裏面就是作上面三件事啦
作完這些就能夠實現漸變了,項目中用的比較多的話直接繼承設置一下參數就能夠了。
demon地址:https://github.com/yizhixiafancai/ShadeViewController