iOS实现知乎和途家导航栏渐变的文字动画效果
程序员文章站
2023-12-18 07:59:21
效果图如下
分析如下:
1.导航栏一开始是隐藏的,随着scrollview滚动而渐变
&...
效果图如下
分析如下:
1.导航栏一开始是隐藏的,随着scrollview滚动而渐变
2.导航栏左右两边的navigationitem是一直显示的
3.导航栏参考了途家app,使用了毛玻璃效果,背景是一张图片
4.下拉放大图片效果
5.title文字动画效果
通过简单分析,系统的导航栏实现以上效果有点困难,直接自定义一个假的导航栏更容易点
分布拆解实现以上效果
一.下拉放大header图片
- (void)viewdidload { [super viewdidload]; [self.view addsubview:self.scaleimageview]; // 设置展示图片的约束 [_scaleimageview mas_makeconstraints:^(masconstraintmaker *make) { make.top.mas_equalto(0); make.left.equalto(self.view.mas_left); make.right.equalto(self.view.mas_right); make.height.mas_equalto(kheardh); }]; } // tableview懒加载 -(uitableview *)tableview{ if(_tableview == nil){ _tableview = [[uitableview alloc]initwithframe:self.view.bounds style:uitableviewstyleplain]; _tableview.contentinset = uiedgeinsetsmake(kheardh-35, 0, 0, 0); _tableview.delegate = self; _tableview.datasource = self; _tableview.separatorstyle = uitableviewcellseparatorstylenone; } return _tableview; } // 图片的懒加载 - (uiimageview *)scaleimageview { if (!_scaleimageview) { _scaleimageview = [[uiimageview alloc] init]; _scaleimageview.contentmode = uiviewcontentmodescaleaspectfill; _scaleimageview.clipstobounds = yes; _scaleimageview.image = [uiimage imagenamed:@"666"]; } return _scaleimageview; } // 导航栏高度 #define knavbarh 64.0f // 头部图片的高度 #define kheardh 260 #pragma mark - uiscrollviewdelegate - (void)scrollviewdidscroll:(uiscrollview *)scrollview { // 计算当前偏移位置 cgfloat offsety = scrollview.contentoffset.y; cgfloat delta = offsety - _lastoffsety; dlog(@"delta=%f",delta); dlog(@"offsety=%f",offsety); cgfloat height = kheardh - delta; if (height < knavbarh) { height = knavbarh; } [_scaleimageview mas_updateconstraints:^(masconstraintmaker *make) { make.height.mas_equalto(height); }]; }
二.导航栏左右两边的navigationitem是一直显示的
- (void)viewdidload { [super viewdidload]; // 直接添加到控制器的view上面,注意添加顺序,在添加导航栏之后,否则会被遮盖住 [self confignavigationbar]; } - (void)confignavigationbar{ //左边返回按钮 uibutton *backbtn = [[uibutton alloc]init]; backbtn.frame = cgrectmake(0, 20, 44, 44); [backbtn setimage:[uiimage imagenamed:@"special_back"] forstate:uicontrolstatenormal]; [backbtn addtarget:self action:@selector(back) forcontrolevents:uicontroleventtouchupinside]; //右边分享按钮 uibutton *shartbtn = [[uibutton alloc]init]; shartbtn.frame = cgrectmake(screenwidth-44, 20, 44, 44); [shartbtn setimage:[uiimage imagenamed:@"special_share"] forstate:uicontrolstatenormal]; [shartbtn addtarget:self action:@selector(sharebtnclick) forcontrolevents:uicontroleventtouchupinside]; [self.view addsubview:backbtn]; [self.view addsubview:shartbtn]; } // 返回 -(void)back{ [self.navigationcontroller popviewcontrolleranimated:yes]; }
三.自定义导航栏及毛玻璃效果及title文字动画效果
// 隐藏系统导航栏 - (void)viewwillappear:(bool)animated{ [super viewwillappear:animated]; self.navigationcontroller.navigationbar.hidden = yes; } - (void)viewdidload { [super viewdidload]; self.navigationcontroller.navigationbar.hidden = yes; self.lastoffsety = - kheardh+35; [self.view addsubview:self.tableview]; self.tableview.backgroundcolor = [uicolor clearcolor]; [self.view addsubview:self.navigationview]; self.navigationcontroller.navigationbar.barstyle = uibarstyleblack; } // 自定义导航栏 -(uiview *)navigationview{ if(_navigationview == nil){ _navigationview = [[uiview alloc]init]; _navigationview.frame = cgrectmake(0, 0, screenwidth, knavbarh); _navigationview.backgroundcolor = [uicolor clearcolor]; _navigationview.alpha = 0.0; //添加子控件 [self setnavigationsubview]; } return _navigationview; } // 注意:毛玻璃效果api是ios8的,适配ios8以下的请用其他方法 -(void)setnavigationsubview{ // 毛玻璃背景 uiimageview *bgimgview = [[uiimageview alloc] initwithframe:_navigationview.bounds]; bgimgview.image = [uiimage imagenamed:@"666"]; [_navigationview addsubview:bgimgview]; /** 毛玻璃特效类型 * uiblureffectstyleextralight, * uiblureffectstylelight, * uiblureffectstyledark */ uiblureffect * blureffect = [uiblureffect effectwithstyle:uiblureffectstyledark]; // 毛玻璃视图 uivisualeffectview * effectview = [[uivisualeffectview alloc] initwitheffect:blureffect]; //添加到要有毛玻璃特效的控件中 effectview.frame = bgimgview.bounds; [bgimgview addsubview:effectview]; //设置模糊透明度 effectview.alpha = 0.9f; //中间文本框 uiview *centertextview = [[uiview alloc]init]; self.centertextview = centertextview; cgfloat centertextviewx = 0; cgfloat centertextviewy = 64; cgfloat centertextvieww = 0; cgfloat centertextviewh = 0; //文字大小 nsstring *title = @"pg.lostk开启后摇滚的新图景"; nsstring *desc = @"摇滚清心坊8套"; cgsize titlesize = [title sizewithattributes:@{nsfontattributename:[uifont systemfontofsize:12]}]; cgsize descsize = [desc sizewithattributes:@{nsfontattributename:[uifont systemfontofsize:11]}]; centertextvieww = titlesize.width > descsize.width ? titlesize.width : descsize.width; centertextviewh = titlesize.height + descsize.height +10; centertextviewx = (screenwidth - centertextvieww) / 2; centertextview.frame = cgrectmake(centertextviewx, centertextviewy, centertextvieww, centertextviewh); //文字label uilabel *titlelabel = [[uilabel alloc]init]; titlelabel.text = title; titlelabel.font = [uifont systemfontofsize:12]; titlelabel.textcolor = [uicolor whitecolor]; titlelabel.frame = cgrectmake(0,5, centertextvieww, titlesize.height); uilabel *desclabel = [[uilabel alloc]init]; desclabel.textalignment = nstextalignmentcenter; desclabel.text = desc; desclabel.font = [uifont systemfontofsize:11]; desclabel.textcolor = [uicolor whitecolor]; desclabel.frame = cgrectmake(0, titlesize.height + 5, centertextvieww, descsize.height); [centertextview addsubview:titlelabel]; [centertextview addsubview:desclabel]; [_navigationview addsubview:centertextview]; } 声明控件 @property(nonatomic,strong) uiview *navigationview; // 导航栏 @property(nonatomic,strong) uiview *centertextview; // title文字 @property (assign, nonatomic) cgfloat lastoffsety; // 记录上一次位置 @property (nonatomic,strong) uiimageview *scaleimageview; // 顶部图片 核心代码 #pragma mark - scrollviewdelegate - (void)scrollviewdidscroll:(uiscrollview *)scrollview { // 计算当前偏移位置 cgfloat offsety = scrollview.contentoffset.y; cgfloat delta = offsety - _lastoffsety; dlog(@"delta=%f",delta); dlog(@"offsety=%f",offsety); cgfloat height = kheardh - delta; if (height < knavbarh) { height = knavbarh; } cgfloat margin = 205; if (delta>margin && delta<margin+39) { self.centertextview.y = 64 - (delta-margin); self.centertextview.alpha = 1.0; } if (delta>margin+39) { self.centertextview.y = 25; self.centertextview.alpha = 1.0; } if (delta<=margin) { self.centertextview.alpha = 0; } if (delta<= 0) { self.centertextview.y =64; self.centertextview.alpha = 0.0; } [_scaleimageview mas_updateconstraints:^(masconstraintmaker *make) { make.height.mas_equalto(height); }]; cgfloat alpha = delta / (kheardh - knavbarh); if (alpha >= 1.0) { alpha = 1.0; } self.navigationview.alpha = alpha; }
总结
以上就是这篇文章的全部内容,希望对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。