iOS之网易效果
代码:https://gitee.com/lanyingwei/codes/eif1n95gctksl7jxp6u0m97
这个是高仿了一个百思不得姐,然后里面的标题栏是固定死了的。比较局限,于是又写了一个滚动的标题栏。就和网易效果非常像了。看效果图
wyxg.gif
实现思路:
1.利用控制器的父子关系,还有UIScrollView的一些代理方法,还有标题栏UILable添加手势点击事件去联动。
2.标题栏使用一个UIScrollView,偏移量就是自控制器的个数乘以每隔标题的宽度。给UILable添加手势,点击让UIScrollView滚动到对应标题的控制器
3.中间内容使用一个UIScorllView去装所有子控制器的View, 利用UIScrollView的代理方法,手动拖拽滚动时候,让标题也对应滚动。
主要代码
注意我这里的两个UIScrollView是利用xib拖拽的。
源码:https://github.com/LYWGod/wyxg
#import "NewsViewController.h" #import "TopLineViewController.h" #import "HotViewController.h" #import "SocietyViewController.h" #import "VideoViewController.h" #import "ReaderViewController.h" #import "ScienceViewController.h" static CGFloat const labelW = 100; // 标题文字宽度 static CGFloat const radio = 1.3; // 点击或者滑动scrollView 标题Label放大倍数 #define KscreenWidth [UIScreen mainScreen].bounds.size.width #define KscreenHeight [UIScreen mainScreen].bounds.size.height @interface NewsViewController ()<UIScrollViewDelegate> @property (nonatomic, weak) UILabel *selLabel; @property (weak, nonatomic) IBOutlet UIScrollView *titleScrollView; @property (weak, nonatomic) IBOutlet UIScrollView *contentScrollView; @property (nonatomic, strong) NSMutableArray *titleLabels; @end @implementation NewsViewController /* 网易新闻实现步骤: 1.搭建结构(导航控制器) * 自定义导航控制器根控制器NewsViewController * 搭建NewsViewController界面(上下滚动条) * 确定NewsViewController有多少个子控制器,添加子控制器 2.设置上面滚动条标题 * 遍历所有子控制器 3.监听滚动条标题点击 * 3.1 让标题选中,文字变为红色 * 3.2 滚动到对应的位置 * 3.3 在对应的位置添加子控制器view 4.监听滚动完成时候 * 4.1 在对应的位置添加子控制器view * 4.2 选中子控制器对应的标题 */ - (void)viewDidLoad { [super viewDidLoad]; // 1.添加所有子控制器 [self setUpChildViewController]; // 2.添加所有子控制器对应标题 [self setUpTitleLabel]; // iOS7会给导航控制器下所有的UIScrollView顶部添加额外滚动区域 // 不想要添加 self.automaticallyAdjustsScrollViewInsets = NO; // 3.初始化UIScrollView [self setUpScrollView]; } // 初始化UIScrollView - (void)setUpScrollView { NSUInteger count = self.childViewControllers.count; // 设置标题滚动条 self.titleScrollView.contentSize = CGSizeMake(count * labelW, 0); self.titleScrollView.showsHorizontalScrollIndicator = NO; // 设置内容滚动条 self.contentScrollView.contentSize = CGSizeMake(count * KscreenWidth, 0); // 开启分页 self.contentScrollView.pagingEnabled = YES; // 没有弹簧效果 self.contentScrollView.bounces = NO; // 隐藏水平滚动条 self.contentScrollView.showsHorizontalScrollIndicator = NO; // 设置代理 self.contentScrollView.delegate = self; } // 添加所有子控制器对应标题 - (void)setUpTitleLabel { NSUInteger count = self.childViewControllers.count; CGFloat labelX = 0; CGFloat labelY = 0; CGFloat labelH = 44; for (int i = 0; i < count; i++) { // 获取对应子控制器 UIViewController *vc = self.childViewControllers[i]; // 创建label UILabel *label = [[UILabel alloc] init]; labelX = i * labelW; // 设置尺寸 label.frame = CGRectMake(labelX, labelY, labelW, labelH); // 设置label文字 label.text = vc.title; // 设置高亮文字颜色 label.highlightedTextColor = [UIColor redColor]; // 设置label的tag label.tag = i; // 设置用户的交互 label.userInteractionEnabled = YES; // 文字居中 label.textAlignment = NSTextAlignmentCenter; // 添加到titleLabels数组 [self.titleLabels addObject:label]; // 添加点按手势 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(titleClick:)]; [label addGestureRecognizer:tap]; // 默认选中第0个label if (i == 0) { [self titleClick:tap]; } // 添加label到标题滚动条上 [self.titleScrollView addSubview:label]; } } // 设置标题居中 - (void)setUpTitleCenter:(UILabel *)centerLabel { // 计算偏移量 CGFloat offsetX = centerLabel.center.x - KscreenWidth * 0.5; if (offsetX < 0) offsetX = 0; // 获取最大滚动范围 CGFloat maxOffsetX = self.titleScrollView.contentSize.width - KscreenWidth; if (offsetX > maxOffsetX) offsetX = maxOffsetX; // 滚动标题滚动条 [self.titleScrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES]; } #pragma mark - UIScrollViewDelegate // scrollView一滚动就会调用 - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat curPage = scrollView.contentOffset.x / scrollView.bounds.size.width; // 左边label角标 NSInteger leftIndex = curPage; // 右边的label角标 NSInteger rightIndex = leftIndex + 1; // 获取左边的label UILabel *leftLabel = self.titleLabels[leftIndex]; // 获取右边的label UILabel *rightLabel; if (rightIndex < self.titleLabels.count - 1) { rightLabel = self.titleLabels[rightIndex]; } // 计算下右边缩放比例 CGFloat rightScale = curPage - leftIndex; NSLog(@"rightScale--%f",rightScale); // 计算下左边缩放比例 CGFloat leftScale = 1 - rightScale; NSLog(@"leftScale--%f",leftScale); // 0 ~ 1 // 1 ~ 2 // 左边缩放 leftLabel.transform = CGAffineTransformMakeScale(leftScale * 0.3 + 1, leftScale * 0.3+ 1); // 右边缩放 rightLabel.transform = CGAffineTransformMakeScale(rightScale * 0.3 + 1, rightScale * 0.3+ 1); // 设置文字颜色渐变 /* R G B 黑色 0 0 0 红色 1 0 0 */ leftLabel.textColor = [UIColor colorWithRed:leftScale green:0 blue:0 alpha:1]; rightLabel.textColor = [UIColor colorWithRed:rightScale green:0 blue:0 alpha:1]; NSLog(@"%f",curPage); } #pragma mark - 结束滚动 需要做的事情 - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ // 计算滚动到哪一页 NSInteger index = scrollView.contentOffset.x / scrollView.bounds.size.width; // CGFloat offsetX = scrollView.contentOffset.x; // 1.添加子控制器view [self showVc:index]; // 2.把对应的标题选中 UILabel *selLabel = self.titleLabels[index]; [self selectLabel:selLabel]; // 3.让选中的标题居中 [self setUpTitleCenter:selLabel]; } // 显示控制器的view - (void)showVc:(NSInteger)index { CGFloat offsetX = index * KscreenWidth; UIViewController *vc = self.childViewControllers[index]; // 判断控制器的view有没有加载过,如果已经加载过,就不需要加载 if (vc.isViewLoaded) return; [self.contentScrollView addSubview:vc.view]; vc.view.frame = CGRectMake(offsetX, 0, KscreenWidth, KscreenHeight); } // 点击标题的时候就会调用 - (void)titleClick:(UITapGestureRecognizer *)tap { // 0.获取选中的label UILabel *selLabel = (UILabel *)tap.view; // 1.标题颜色变成红色,设置高亮状态下的颜色 [self selectLabel:selLabel]; // 2.滚动到对应的位置 NSInteger index = selLabel.tag; // 2.1 计算滚动的位置 CGFloat offsetX = index * KscreenWidth; self.contentScrollView.contentOffset = CGPointMake(offsetX, 0); // 3.给对应位置添加对应子控制器 [self showVc:index]; // 4.让选中的标题居中 [self setUpTitleCenter:selLabel]; } // 选中label - (void)selectLabel:(UILabel *)label { // 取消之前Label高亮 _selLabel.highlighted = NO; // 取消之前Label形变 _selLabel.transform = CGAffineTransformIdentity; // 恢复之前Label颜色 _selLabel.textColor = [UIColor blackColor]; // 高亮当前label label.highlighted = YES; // 形变当前label label.transform = CGAffineTransformMakeScale(radio, radio); // 记录当前label _selLabel = label; } // 添加所有子控制器 - (void)setUpChildViewController { // 头条 TopLineViewController *topLine = [[TopLineViewController alloc] init]; topLine.title = @"头条"; [self addChildViewController:topLine]; // 热点 HotViewController *hot = [[HotViewController alloc] init]; hot.title = @"热点"; [self addChildViewController:hot]; // 视频 VideoViewController *video = [[VideoViewController alloc] init]; video.title = @"视频"; [self addChildViewController:video]; // 社会 SocietyViewController *society = [[SocietyViewController alloc] init]; society.title = @"社会"; [self addChildViewController:society]; // 阅读 ReaderViewController *reader = [[ReaderViewController alloc] init]; reader.title = @"阅读"; [self addChildViewController:reader]; // 科技 ScienceViewController *science = [[ScienceViewController alloc] init]; science.title = @"科技"; [self addChildViewController:science]; } // 懒加载 - (NSMutableArray *)titleLabels { if (_titleLabels == nil) { _titleLabels = [NSMutableArray array]; } return _titleLabels; }