热门标签 | HotTags
当前位置:  开发笔记 > IOS > 正文

iOS仿新闻tab标题栏效果

这篇文章主要为大家详细介绍了iOS仿新闻tab标题栏效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

iOS仿网易新闻之类的滑动标题栏,供大家参考,具体内容如下

预览

思路

两个scorllview,一个用于标题栏,一个拥有底下的page
标题栏文字和效果切换,渐变色和大小都是根据底下的page偏移量来归一化换算的
小横线直接加载标题栏所在的scorllview里面,小横线自身要有局部偏移,根据page来切换
标题栏的居中需要算一个scrollview的偏移量,小横线跟着scorllview偏移
监听scrollview的滑动和停止滑动进行相应的处理

- (void)viewDidLoad
{
 [super viewDidLoad];
 // Do any additional setup after loading the view.
 [self createTitleScrollView];
 [self createButtonLine];
 [self createContentScrollview];
}
 
#pragma mark - 初始化UI
- (void)createTitleScrollView
{
 // 根据是否有导航栏调整坐标
 CGFloat marginY = self.navigationController ? self.navigationController.view.frame.size.height : kUpMargin;
 
 // 标题栏,包括小横线的位置
 _titleScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, marginY, kFrameWidth, kTitleHeight + kButtonLineHeight)];
 _titleScrollView.showsHorizOntalScrollIndicator= NO;
 _titleScrollView.bounces = NO;
 _titleScrollView.delegate = self;
 [self.view addSubview:_titleScrollView];
 
 // 添加button
 NSArray *titleArray = @[@"头条", @"社会", @"财经", @"科技", @"体育", @"娱乐", @"时尚", @"军事", @"教育", @"游戏"];
 _pageCount = titleArray.count;
 _titleScrollView.cOntentSize= CGSizeMake(kButtonWidth * _pageCount, kTitleHeight);
 for (int i = 0; i <_pageCount; i++)
 {
  UIButton *titleBtn = [[UIButton alloc] initWithFrame:CGRectMake(kButtonWidth * i, 0, kButtonWidth, kTitleHeight)];
  [titleBtn setTitle:titleArray[i] forState:UIControlStateNormal];
  [titleBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  titleBtn.titleLabel.fOnt= [UIFont systemFontOfSize:16];
  [titleBtn addTarget:self action:@selector(titleButtonClicked:) forControlEvents:UIControlEventTouchDown];
  titleBtn.tag = 1000 + i; // button做标记,方便后面索引,为了不出冲突,就把这个数值设得大一些
  [_titleScrollView addSubview:titleBtn];
 };
}
 
- (void)createButtonLine
{
 // 初始时刻停在最左边与按钮对齐
 _buttOnLine= [[UIView alloc] initWithFrame:CGRectMake(0, kTitleHeight, kButtonWidth, kButtonLineHeight)];
 _buttonLine.backgroundColor = [UIColor redColor];
 // 小横线加载scrollview上才能跟随button联动
 [_titleScrollView addSubview:_buttonLine];
}
 
- (void)createContentScrollview
{
 CGFloat marginY = self.navigationController &#63; self.navigationController.view.frame.size.height : kUpMargin;
 
 // 添加内容页面
 _cOntentScrollview= [[UIScrollView alloc] initWithFrame:CGRectMake(0, marginY + kTitleHeight + kButtonLineHeight, kFrameWidth, kFrameHeight - marginY - kTitleHeight - kButtonLineHeight)];
 _contentScrollview.pagingEnabled = YES;
 _contentScrollview.bounces = NO;
 _contentScrollview.cOntentSize= CGSizeMake(kFrameWidth * _pageCount, kFrameHeight - marginY - kTitleHeight);
 _contentScrollview.showsHorizOntalScrollIndicator= NO;
 _contentScrollview.delegate = self;
 [self.view addSubview:_contentScrollview];
 
 // 添加分页面
 for (int i = 0; i <_pageCount; i++)
 {
  PageViewController *pageViewCOntroller= [[PageViewController alloc] init];
  UIButton *button = [_titleScrollView viewWithTag:1000 + i];
  pageViewController.title = button.currentTitle;
  pageViewController.view.frame = CGRectMake(kFrameWidth * i, 0, kFrameWidth, kFrameHeight - marginY - kTitleHeight);
  [_contentScrollview addSubview:pageViewController.view];
 }
 
 // 初始化后选中某个栏目
 [self titleButtonClicked:[_titleScrollView viewWithTag:1000 + 0]];
}
 
#pragma mark - 标题button点击事件
- (void)titleButtonClicked:(UIButton *)sender
{
 // 根据点击的button切换页面和偏移
 printf("%s clicked\n", sender.currentTitle.UTF8String);
 
 // 以下不用了,因为scroll切换会自动处理好尺寸和颜色了
// for (int i = 0; i <_pageCount; i++)
// {
//  UIButton *button = [_titleScrollView viewWithTag:1000 + i];
//  // 重置button尺寸颜色
//  button.transform = CGAffineTransformMakeScale(1, 1);
//  [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
// }
 
 // 强调被选中的button
 // 放大聚焦
 sender.transform = CGAffineTransformMakeScale(kMaxTitleScale, kMaxTitleScale);
 // 变色
 [sender setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
 
 // 居中title
 [self settleTitleButton:sender];
 
 // 带动画切换到对应的内容,会触发scrollViewDidScroll
 NSInteger pageIndex = sender.tag - 1000;
 [_contentScrollview setContentOffset:CGPointMake(kFrameWidth * pageIndex, 0) animated:YES];
}
 
#pragma mark - scrollview滑动事件
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
 // 根据content内容偏移调整标题栏
 if (scrollView == _titleScrollView)
 {
  printf("title moved\n");
  
  
 }
 else if (scrollView == _contentScrollview)
 {
  printf("content moved\n");
  
  // 获得左右两个button的索引, 注意最后取整
  CGFloat offsetX = scrollView.contentOffset.x;
  NSInteger leftTitleIndex = offsetX / kFrameWidth;
  NSInteger rightTitleIndex = leftTitleIndex + 1;
  // 因为设置了到边不能滑动,所以不考虑边界
  UIButton *leftTitleButton = [_titleScrollView viewWithTag:1000 + leftTitleIndex];
  UIButton *rightTitleButton = [_titleScrollView viewWithTag:1000 + rightTitleIndex];
  
  // 设置大小和颜色渐变以及小横线的联动
  // 权重因子 0~1 小数, 左边和右边互补
  CGFloat rightTitleFactor = offsetX / kFrameWidth - leftTitleIndex;
  CGFloat leftTitleFactor = 1 - rightTitleFactor;
  
  // 尺寸
  CGFloat maxExtraScale = kMaxTitleScale - 1;
  leftTitleButton.transform = CGAffineTransformMakeScale(1 + leftTitleFactor * maxExtraScale, 1 + leftTitleFactor * maxExtraScale);
  rightTitleButton.transform = CGAffineTransformMakeScale(1 + rightTitleFactor * maxExtraScale, 1 + rightTitleFactor * maxExtraScale);
  // 颜色
  UIColor *leftTitleColor = [UIColor colorWithRed:0 green:leftTitleFactor blue:0 alpha:1];
  UIColor *rightTitleColor = [UIColor colorWithRed:0 green:rightTitleFactor blue:0 alpha:1];
  [leftTitleButton setTitleColor:leftTitleColor forState:UIControlStateNormal];
  [rightTitleButton setTitleColor:rightTitleColor forState:UIControlStateNormal];
  // 小横线位移
  _buttonLine.frame = CGRectMake(kButtonWidth * (leftTitleIndex + rightTitleFactor), _buttonLine.frame.origin.y, kButtonWidth, kButtonLineHeight);
 }
}
 
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
 // 内容区块滑动结束调整标题栏居中
 if (scrollView == _contentScrollview)
 {
  // 取得索引值
  NSInteger titleIndex = scrollView.contentOffset.x / kFrameWidth;
  // title居中
  [self settleTitleButton:[_titleScrollView viewWithTag:1000 + titleIndex]];
 }
}
 
#pragma mark - 标题按钮和横线居中偏移
- (void)settleTitleButton:(UIButton *)button
{
 // 标题
 // 这个偏移量是相对于scrollview的content frame原点的相对对标
 CGFloat deltaX = button.center.x - kFrameWidth / 2;
 // 设置偏移量,记住这段算法
 if (deltaX <0)
 {
  // 最左边
  deltaX = 0;
 }
 CGFloat maxDeltaX = _titleScrollView.contentSize.width - kFrameWidth;
 if (deltaX > maxDeltaX)
 {
  // 最右边不能超范围
  deltaX = maxDeltaX;
 }
 [_titleScrollView setContentOffset:CGPointMake(deltaX, 0) animated:YES];
 
}

源代码下载

csdn:仿网易新闻tab效果

github:仿网易新闻tab效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • Redux入门指南
    本文介绍Redux的基本概念和工作原理,帮助初学者理解如何使用Redux管理应用程序的状态。Redux是一个用于JavaScript应用的状态管理库,特别适用于React项目。 ... [详细]
  • 历经三十年的开发,Mathematica 已成为技术计算领域的标杆,为全球的技术创新者、教育工作者、学生及其他用户提供了一个领先的计算平台。最新版本 Mathematica 12.3.1 增加了多项核心语言、数学计算、可视化和图形处理的新功能。 ... [详细]
  • 本文将详细介绍多个流行的 Android 视频处理开源框架,包括 ijkplayer、FFmpeg、Vitamio、ExoPlayer 等。每个框架都有其独特的优势和应用场景,帮助开发者更高效地进行视频处理和播放。 ... [详细]
  • Python 工具推荐 | PyHubWeekly 第二十一期:提升命令行体验的五大工具
    本期 PyHubWeekly 为大家精选了 GitHub 上五个优秀的 Python 工具,涵盖金融数据可视化、终端美化、国际化支持、图像增强和远程 Shell 环境配置。欢迎关注并参与项目。 ... [详细]
  • 版本控制工具——Git常用操作(下)
    本文由云+社区发表作者:工程师小熊摘要:上一集我们一起入门学习了git的基本概念和git常用的操作,包括提交和同步代码、使用分支、出现代码冲突的解决办法、紧急保存现场和恢复 ... [详细]
  • Android 6.0 切换指定 Wi-Fi 的解决方案
    本文详细介绍了在 Android 6.0 系统中切换到指定 Wi-Fi 的方法,包括常见的问题、原因分析及解决方案。通过官方文档和代码示例,帮助开发者更好地理解和实现这一功能。 ... [详细]
  • 本文介绍了如何通过Java代码计算一个整数的位数,并展示了多个基础编程示例,包括求和、平均分计算、条件判断等。 ... [详细]
  • 简化报表生成:EasyReport工具的全面解析
    本文详细介绍了EasyReport,一个易于使用的开源Web报表工具。该工具支持Hadoop、HBase及多种关系型数据库,能够将SQL查询结果转换为HTML表格,并提供Excel导出、图表显示和表头冻结等功能。 ... [详细]
  • 本文介绍如何从JSON格式的文件中提取数据并将其分配给Bash脚本中的变量。我们将探讨具体的命令和工具,帮助你高效地完成这一任务。 ... [详细]
  • gitlab配置免密拉取推送
    目录一.简介二.配置一.简介gitlab默认提供HTTPSSH两种请求方式下载代码测试用的gitlab账号账号:abc密码:123456二.配置1.生成秘钥,一路回车即可cd~ss ... [详细]
  • 如何使用 CleanMyMac X 2023 激活码解锁完整功能
    本文详细介绍了如何使用 CleanMyMac X 2023 激活码解锁软件的全部功能,并提供了一些优化和清理 Mac 系统的专业建议。 ... [详细]
  • 解决MacOS上Android Studio Gradle版本不匹配问题
    在MacOS系统中,升级Android Studio后可能会遇到Gradle版本不兼容的问题。当网络下载更新受阻时,可以使用本地已安装的Gradle版本来解决问题。本文将详细介绍如何配置本地Gradle环境以确保开发工作的顺利进行。 ... [详细]
  • Go语言实现经典排序算法:归并排序
    本文介绍如何使用Go语言实现经典的归并排序算法,探讨其原理、代码实现及性能特点。适合Golang开发者和编程爱好者。 ... [详细]
  • 深入理解Java多线程并发处理:基础与实践
    本文探讨了Java中的多线程并发处理机制,从基本概念到实际应用,帮助读者全面理解并掌握多线程编程技巧。通过实例解析和理论阐述,确保初学者也能轻松入门。 ... [详细]
  • 本文深入探讨了MySQL中常见的面试问题,包括事务隔离级别、存储引擎选择、索引结构及优化等关键知识点。通过详细解析,帮助读者在面对BAT等大厂面试时更加从容。 ... [详细]
author-avatar
PLDLYY
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有