效果图如下:
项目调用顺序:
1. 初始化标题scrollView --> 2.初始化内容scrollView --> 3. 添加所有子控制器 setupAllChildViewController
--> 4. 设置所有标题 setupTitle --> 5. 标题点击方法 titleChilk: --> 6. 点击标题时,改变标题颜色 switchColor:
--> 7. 设置标题选中居中 setupTitleCenter: --> 8. 点击标题,将对应的子控制器View添加到内容scrollView上 addOneViewController: --> 9. 设置代理,监听内容scrollView滚动 --> 10. 调用 滚动完成的时候 和 滚动时的方法
ZYViewController文件 : ViewController.
// Created by 朝阳 on 2018/2/6.
// Copyright © 2018年 sunny. All rights reserved.
//
#import "ZYViewController.h"
#import "HeadLineViewController.h"
#import "HotViewController.h"
#import "VideoViewController.h"
#import "SocialViewController.h"
#import "SubscribeViewController.h"
#import "ScienceViewController.h"
@interface ZYViewController ()
@end
@implementation ZYViewController
- (void)viewDidLoad {
// 调用父类的viewDidLoad
[super viewDidLoad];
// 添加所有子控制器
[self setupAllChildViewController];
// 当调用玩viewDidLoad后,就会调用viewWillAppear:方法,此类没有该方法,就会去父类找
}
#pragma -mark 添加所有的子控制器 3
- (void)setupAllChildViewController
{
//头条
HeadLineViewController *headLineVC = [[HeadLineViewController alloc] init];
headLineVC.title = @"头条";
/*
在这里设置背景颜色不好,因为当程序运行后,所有的控制器中的内容都加载了出来.
应该点击对应的标题按钮后再去加载,因此把颜色设置在对应控制器的viewDidload里
*/
// headLineVC.view.backgroundColor = [UIColor blueColor];
[self addChildViewController:headLineVC];
//热点
HotViewController *hotVC = [[HotViewController alloc] init];
hotVC.title = @"热点";
[self addChildViewController:hotVC];
//视频
VideoViewController *videoVC = [[VideoViewController alloc] init];
videoVC.title = @"视频";
[self addChildViewController:videoVC];
//社会
SocialViewController *socialVC = [[SocialViewController alloc] init];
socialVC.title = @"社会";
[self addChildViewController:socialVC];
//订阅
SubscribeViewController *subscribeVC = [[SubscribeViewController alloc] init];
subscribeVC.title = @"订阅";
[self addChildViewController:subscribeVC];
//科技
ScienceViewController *scienceVC = [[ScienceViewController alloc] init];
scienceVC.title = @"科技";
[self addChildViewController:scienceVC];
ScienceViewController *scienceVC1 = [[ScienceViewController alloc] init];
scienceVC1.title = @"朝阳";
[self addChildViewController:scienceVC1];
}
@end
ViewController文件
// Created by 朝阳 on 2018/2/5.
// Copyright © 2018年 sunny. All rights reserved.
//
#import "ViewController.h"
#define ScreenW [UIScreen mainScreen].bounds.size.width
@interface ViewController ()
@property (nonatomic, weak) UIScrollView *titleScrollView;
@property (nonatomic, weak) UIScrollView *contentScrollView;
@property (nonatomic, weak) UIButton *selectBtn;
@property (nonatomic, strong) NSMutableArray *btnArray;
@property (nonatomic, assign) BOOL isInitialize;
@end
@implementation ViewController
- (NSMutableArray *)btnArray
{
if (_btnArray == nil) {
NSMutableArray *btnArray = [NSMutableArray array];
_btnArray = btnArray;
}
return _btnArray;
}
#pragma -mark 设置所有标题 4
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//设置标题. 判断只设置一次
if (_isInitialize == NO) {
[self setupTitle];
_isInitialize = YES;
}
}
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"朝阳新闻";
//1. 创建标题scrollView
[self setupTitleScrollView];
//2. 创建内容scrollView
[self setupContentScrollView];
//4. 设置标题
//5. 标题点击
//6. 处理内容滚动,视图滚动(监听scrollView的滚动)
//7. 选中标题居中
//8. 标题缩放及颜色渐变
}
#pragma -mark UIScrollView delegate Method 9
// 滚动完成的时候调用
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
// 根据滚动的偏移量获取当前角标
NSInteger i = scrollView.contentOffset.x / ScreenW;
// 根据角标获取button
// UIButton *button = self.titleScrollView.subviews[i]; // 可能取出的子控件紊乱,scrollView内有系统子控件
UIButton *button = self.btnArray[i];
//1.切换标题颜色
[self switchColor:button];
//2.把对应的子控制器的view添加上去
[self addOneViewController:i];
}
// 滚动的时候调用
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//① 字体缩放 1.缩放比例 2.缩放哪两个按钮
//根据偏移量来获取按钮的角标
NSInteger leftI = scrollView.contentOffset.x / ScreenW;
NSInteger rightI = leftI + 1;
//获取左边的按钮
UIButton *leftBtn = self.btnArray[leftI];
//获取右边的按钮
//防止越界
UIButton *rightBtn;
if (rightI < self.btnArray.count) {
rightBtn = self.btnArray[rightI];
}
// 缩放比例 0 ~ 1 => 1 ~ 1.3 (最大为1.3)
CGFloat scaleR = scrollView.contentOffset.x / ScreenW;
// 始终保持缩放比例为0 ~ 1
scaleR -= leftI;
//NSLog(@"%f",scaleR * 0.3 + 1);
CGFloat scaleL = 1 - scaleR;
//NSLog(@"%f",scaleL);
//缩放按钮
leftBtn.transform = CGAffineTransformMakeScale(scaleL * 0.3 + 1, scaleL * 0.3 + 1);
rightBtn.transform = CGAffineTransformMakeScale(scaleR * 0.3 + 1, scaleR * 0.3 + 1);
//② 颜色渐变
UIColor *rightColor = [UIColor colorWithRed:scaleR green:0 blue:0 alpha:1];
UIColor *leftColor = [UIColor colorWithRed:scaleL green:0 blue:0 alpha:1];
[rightBtn setTitleColor:rightColor forState:UIControlStateNormal];
[leftBtn setTitleColor:leftColor forState:UIControlStateNormal];
/*
白色 1 1 1
黑色 0 0 0
红色 1 0 0
*/
}
#pragma -mark 标题居中 7
- (void)setupTitleCenter:(UIButton *)button
{
//标题居中本质:是标题按钮的偏移量
CGFloat offsetX = button.center.x - ScreenW * 0.5;
// NSLog(@"%f",offsetX);
if (offsetX < 0) {
offsetX = 0;
}
//标题按钮最大的偏移量
CGFloat maxOffsetX = self.titleScrollView.contentSize.width - ScreenW;
// 如果偏移量 > 最大偏移量
if (offsetX > maxOffsetX) {
offsetX = maxOffsetX;
}
[self.titleScrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
}
#pragma -mark 点击标题切换颜色 6
- (void)switchColor:(UIButton *)button
{
self.selectBtn.transform = CGAffineTransformIdentity;
[self.selectBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
// 设置标题选中居中
[self setupTitleCenter:button];
// 设置标题文字缩放
button.transform = CGAffineTransformMakeScale(1.3, 1.3);
self.selectBtn = button;
}
#pragma -mark 添加一个子控制器view 8
static CGFloat x;
- (void)addOneViewController:(NSInteger)i;
{
UIViewController *vc = self.childViewControllers[i];
// 如果此时view的控制器已经添加到contentScrollView上,不再重复添加
//if (vc.viewIfLoaded) {
if(vc.view.superview){
return;
}
x = i * ScreenW;
vc.view.frame = CGRectMake(x, 0, ScreenW, self.contentScrollView.bounds.size.height);
[self.contentScrollView addSubview:vc.view];
}
#pragma -mark 设置标题点击 5
- (void)titleClick:(UIButton *)button
{
NSInteger i = button.tag;
//1.点击标题时,标题颜色变为红色
[self switchColor:button];
//2.点击某个标题,将对应子控制器的view添加上去
[self addOneViewController:i];
//3.内容滚动视图滚动到对应的位置(设置偏移量)
self.contentScrollView.contentOffset = CGPointMake(x, 0);
}
#pragma -mark 设置所有标题
- (void)setupTitle
{
NSInteger count = self.childViewControllers.count;
CGFloat x = 0;
CGFloat y = 0;
CGFloat btnW = 100;
CGFloat btnH = self.titleScrollView.bounds.size.height;
for (NSInteger i = 0; i < count; ++i) {
//创建按钮
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.tag = i;
UIViewController *vc = self.childViewControllers[i];
[btn setTitle:vc.title forState:UIControlStateNormal];
x = i * btnW;
btn.frame = CGRectMake(x, y, btnW, btnH);
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(titleClick:) forControlEvents:UIControlEventTouchUpInside];
// 设置默认选择第一个标题
if (i == 0) {
[self titleClick:btn];
}
[self.btnArray addObject:btn];
[self.titleScrollView addSubview:btn];
}
// 设置标题scrollView滚动范围
self.titleScrollView.contentSize = CGSizeMake(count * btnW, 0);
self.titleScrollView.showsHorizontalScrollIndicator = NO;
// 设置内容的滚动范围
self.contentScrollView.contentSize = CGSizeMake(count * ScreenW, 0);
}
#pragma -mark 初始化标题滚动条 1
- (void)setupTitleScrollView
{
UIScrollView *titleScrollView = [[UIScrollView alloc] init];
// titleScrollView.backgroundColor = [UIColor purpleColor];
CGFloat y = self.navigationController.navigationBarHidden ? 20 : 64;
titleScrollView.frame = CGRectMake(0, y, self.view.bounds.size.width, 44);
[self.view addSubview:titleScrollView];
self.titleScrollView = titleScrollView;
}
#pragma -mark 初始化内容滚动条 2
- (void)setupContentScrollView
{
UIScrollView *contentScrollView = [[UIScrollView alloc] init];
// contentScrollView.backgroundColor = [UIColor grayColor];
CGFloat y = CGRectGetMaxY(self.titleScrollView.frame);
contentScrollView.frame = CGRectMake(0, y, self.view.bounds.size.width, self.view.bounds.size.height - y);
[self.view addSubview:contentScrollView];
self.contentScrollView = contentScrollView;
self.contentScrollView.pagingEnabled = YES;
self.contentScrollView.bounces = NO;
self.contentScrollView.showsHorizontalScrollIndicator = NO;
self.contentScrollView.delegate = self;
}
@end