一 网易功能图
二 需要解决的问题
1> 搭建界面,设置标题
2> 处理标题按钮点击事件,处理常见的bug
3> 监听内容的滚动
4> 滚动范围的判断
5> 字体大小和颜色的渐变
三 内容显示和标题显示搭建
1 思路: 由总体app的效果,我们可以看出,标题和内容界面都是可以滚动的,而且标题还可以点击
3 显示内容的代码:
#pragma mark - 创建控制器内容的scrollView
- (void)setUpChildView
{
UIScrollView *scrollView = [[UIScrollView alloc] init];
CGFloat X = 0;
CGFloat Y = CGRectGetMaxY(self.titleView.frame);
CGFloat W = XFJUIScreenW;
CGFloat H = XFJUIScreenH - Y;
scrollView.frame = CGRectMake(X, Y, W, H);
[self.view addSubview:scrollView];
scrollView.backgroundColor = [UIColor clearColor];
self.scrollView = scrollView;
scrollView.delegate = self;
}
4 内容代码中相关参数
#define XFJUIScreenW [UIScreen mainScreen].bounds.size.width
#define XFJUIScreenH [UIScreen mainScreen].bounds.size.height
5 显示标题的相关代码块:
#pragma mark - 添加标题ScrollView
- (void)setUptitle
{
UIScrollView *titleView = [[UIScrollView alloc] init];
titleView.backgroundColor = [UIColor clearColor];
titleView.frame = CGRectMake(0, 64, XFJUIScreenW, 35);
titleView.showsHorizontalScrollIndicator = NO;
[self.view addSubview:titleView];
self.titleView = titleView;
}
6 创建对应的控制器,并且加入到父控制器中
#pragma mark - 设置控制器
- (void)setUpChildController
{
XFJHotViewController *hvc = [[XFJHotViewController alloc] init];
hvc.title = @"热点";
[self addChildViewController:hvc];
XFJReadViewController *rvc = [[XFJReadViewController alloc] init];
rvc.title = @"订阅";
[self addChildViewController:rvc];
XFJTopLineViewController *tvc = [[XFJTopLineViewController alloc] init];
tvc.title = @"头条";
[self addChildViewController:tvc];
XFJScienceViewController *svc = [[XFJScienceViewController alloc] init];
svc.title = @"科技";
[self addChildViewController:svc];
XFJSocietyViewController *svcr = [[XFJSocietyViewController alloc] init];
svcr.title = @"社会";
[self addChildViewController:svcr];
XFJVideoViewController *vvc = [[XFJVideoViewController alloc] init];
vvc.title = @"视频";
[self addChildViewController:vvc];
}
—-> 属性代码:
/**
* 标题UIScrollView
*/
@property (nonatomic, weak) UIScrollView *titleView;
/**
* 控制器的UIScrollView
*/
@property (nonatomic, weak) UIScrollView *scrollView;
四 bug
2 解决bug
self.automaticallyAdjustsScrollViewInsets = NO;
五 添加标题中的按钮
—–> 具体思路:
5.1 需要知道有多少个按钮:通过取出所有的子控制器的数量(count),然后遍历标题中所有的按钮.
5.2 按钮的尺寸:按钮的y值都是0,但是x的值是随着遍历出来的(i)的增加而变化的.
5.3 按钮的标题:直接根据角标(i)遍历所有的子控制器,通过setTitle来设置按钮的标题.
5.4 按钮的颜色:初步设置按钮的颜色为黑色.
5.5 监听按钮的点击事件:由于需要当用户点击按钮的时候,能有对应的控制器,那么我们就需要监听控制器的点击事件.
—–> 具体部分代码块:
#pragma mark - 设置标题按钮
- (void)setUpTitleBtn
{
NSInteger count = self.childViewControllers.count;
NSInteger btnX = 0;
NSInteger btnY = 0;
NSInteger btnW = 100;
NSInteger btnH = 35;
for (NSInteger i = 0; i < count; i++) {
UIButton *btn = [[UIButton alloc] init];
btn.tag = i;
btnX = i * btnW;
btn.frame = CGRectMake(btnX, btnY, btnW, btnH);
UIViewController *vc = self.childViewControllers[i];
[btn setTitle:vc.title forState:UIControlStateNormal];
[btn addTarget:self action:@selector(setUpBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.titleView addSubview:btn];
六 设置按钮状态(选中和正常)
1 点击按钮的时候当前按钮的颜色变为红色
2 点击完按钮后,添加对应的控制器的view
—–> 具体思路:
1 创建一个记录当前按钮状态的属性
/**
* 选中按钮
*/
@property (nonatomic, weak) UIButton *selectBtn;
2 选中按钮颜色和恢复按钮颜色三个步骤
#pragma mark - 设置选中的按钮状态
- (void)selectBtnClick:(UIButton *)button
{
[self.selectBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
self.selectBtn = button;
}
3 选中了按钮,添加对应的控制器:通过在创建按钮的时候,我们绑定了一个tag属性.利用tag我们直接取出存在父控制器中的子控制器.
#pragma mark - 创建控制器
- (void)setUpOneController:(NSInteger)i
{
UIViewController *vc = self.childViewControllers[i];
CGFloat x = i * XFJUIScreenW;
if ([vc.view superview]) {
return;
}
vc.view.frame = CGRectMake(x, 0, XFJUIScreenW, self.scrollView.bounds.size.height);
[self.scrollView addSubview:vc.view];
}
七 监听按钮
#pragma mark - 实现监听方法
- (void)setUpBtnClick:(UIButton *)btn
{
[self selectBtnClick:btn];
NSInteger i = btn.tag;
[self setUpOneController:i];
CGFloat x = i * XFJUIScreenW;
self.scrollView.contentOffset = CGPointMake(x, 0);
}
1 滑动控制器的view,让对应的按钮选中
2 将要停止拖动的时候,添加相应的控制器(该部分通过传入一个角标i在5.5中就实现了添加,直接调用就可以)
3 如何计算停止拖动的时候的角标呢?(通过获取总的滚动范围 / 屏幕的库宽度)
4 怎么让对应的按钮呈现选中状态呢?(定义一个数字,在创建按钮的时候,将按钮装入定义的可变数组中,然后根据角标取出来)
—->对应的代码:
#pragma mark - scrollView将要停止拖动的时候调用
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSInteger i = scrollView.contentOffset.x / XFJUIScreenW;
UIButton *btn = self.titleButtons[i];
NSLog(@"%@",btn);
[self selectBtnClick:btn];
[self setUpOneController:i];
}
5 在创建按钮的时候我们将创建的按钮都装入可变数组中,并且当按钮的角标为0的时候我们让开始显示UI界面的时候默认按钮的颜色为选中状态
if (i == 0) {
[self setUpBtnClick:btn];
}
[self.titleButtons addObject:btn];
}
6 设置标题和显示控制器内容的view是可以滚动的(默认如果不设置的话是不能滚动),并且设置隐藏底部的显示条
CGFloat scope = count * btnW;
self.titleView.contentSize = CGSizeMake(scope, 0);
self.scrollView.pagingEnabled = YES;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.contentSize = CGSizeMake(count * XFJUIScreenW, 0);
九 设置标题的逻辑
1 随着滑动顶部titleView和滑动控制器的view,选中的按钮处在居中的状态,并且控制顶部titleView的滚动位置,不是所有的标题都需要处于居中状态.
——> 代码部分:
#pragma mark - 设置选中的按钮状态
- (void)selectBtnClick:(UIButton *)button
{
[self.selectBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
self.selectBtn.transform = CGAffineTransformIdentity;
[button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
CGFloat offsetX = button.center.x - XFJUIScreenW * 0.5;
if (offsetX < 0) {
offsetX = 0;
}
CGFloat offmax = self.titleView.contentSize.width - XFJUIScreenW;
if (offsetX > offmax) {
offsetX = offmax;
}
[self.titleView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
button.transform = CGAffineTransformMakeScale(1.3, 1.3);
self.selectBtn = button;
}
#pragma mark - 设置滑动的时候字体的放缩(代理方法,滚动标题就会缩放)
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSInteger leftI = scrollView.contentOffset.x / XFJUIScreenW;
UIButton *leftBtn = self.titleButtons[leftI];
NSInteger rightI = leftI + 1;
UIButton *rightButton;
if (rightI < self.titleButtons.count) {
rightButton = self.titleButtons[rightI];
}
CGFloat rightScale = scrollView.contentOffset.x / XFJUIScreenW - leftI;
CGFloat leftScale = 1 - rightScale;
rightButton.transform = CGAffineTransformMakeScale(rightScale * 0.3 + 1,rightScale * 0.3 + 1 );
leftBtn.transform = CGAffineTransformMakeScale(leftScale * 0.3 + 1, leftScale * 0.3 + 1);
UIColor *rightColor = [UIColor colorWithRed:rightScale green:0 blue:0 alpha:1];
[rightButton setTitleColor:rightColor forState:UIControlStateNormal];
UIColor *leftColor = [UIColor colorWithRed:leftScale green:0 blue:0 alpha:1];
[leftBtn setTitleColor:leftColor forState:UIControlStateNormal];
}
十 完善
1 将创建控制器设置的颜色放到对应的子控制器中,让他们自己管理
2 创建一个继承父控制器的子控制器,将创建控制器的所有方法添加到单独的子控制器中.
3 在父控件中写view将要显示的代码,在该代码中添加显示标题的按钮的代码块.因为需要让控制器添加的子控制器都添加上去了,才能显示按钮,否则运行起来不会有内容
#pragma mark - 在view即将显示的时候添加标题,保证viewDidLoad的中的代码都执行完了.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (self.isInitial == NO) {
[self setUpTitleBtn];
self.isInitial = YES;
}
}
十一 总结
1 这是是演示的部分,比如这种界面,如果界面多的话,建议UICollectionView,否则加载数据的时候,会卡死.
3 OK就这么多,有什么建议,还是麻烦大家留言,谢谢!!!!