欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS实现知乎和途家导航栏渐变的文字动画效果

程序员文章站 2023-12-14 22:57:58
效果图如下 分析如下:      1.导航栏一开始是隐藏的,随着scrollview滚动而渐变   &...

效果图如下

iOS实现知乎和途家导航栏渐变的文字动画效果

分析如下:

     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;
}

总结

以上就是这篇文章的全部内容,希望对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。

上一篇:

下一篇: