效果图:
需求:当滑动页面时,上面的标题按钮也跟着滑动到相应的位置
分析:
(1)标题栏----UIView
(2)标题按钮
(3)标题按钮下的下划线
代码:
/**
* 标题栏
*/
- (void)setupTitleView
{
// 标题栏
UIView *titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 44+20, self.view.xmg_width, 35)];
titleView.backgroundColor = [UIColor greenColor];
[self.view addSubview:titleView];
self.titleView = titleView;
// 标题按钮
[self setupTitleButtons];
// 标题下划线
[self setupTitleUnderLine];
}
/**
* 标题栏按钮
*/
- (void)setupTitleButtons
{
// 文字
NSArray *titles = @[@"全部",@"视频",@"声音",@"图片",@"段子"];
NSUInteger count = titles.count;
for (NSUInteger i = 0; i < count; i++) {
BSTitleButton *titleBtn = [[BSTitleButton alloc] init];
// frame
CGFloat titleBtnW = self.titleView.xmg_width / count;
CGFloat titleBtnH = self.titleView.xmg_height;
titleBtn.frame = CGRectMake(i * titleBtnW, 0, titleBtnW, titleBtnH);
// titleBtn.backgroundColor = BSRandomColor;
[titleBtn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
// 将文字添加到对应大btn上
[titleBtn setTitle:titles[i] forState:UIControlStateNormal];
[self.titleView addSubview:titleBtn];
}
}
/**
* 标题栏下划线
*/
- (void)setupTitleUnderLine
{
BSTitleButton *firstbtn = self.titleView.subviews.firstObject;
// 下划线
UIView *line = [[UIView alloc] init];
line.xmg_height = 2;
line.xmg_y = self.titleView.xmg_height - line.xmg_height;
line.backgroundColor = [firstbtn titleColorForState:UIControlStateSelected];
[self.titleView addSubview:line];
self.titleUnderLine = line;
// 第一个按钮状态
firstbtn.selected = YES;
self.previousBtn = firstbtn;
[firstbtn.titleLabel sizeToFit]; // 让label根据文字内容计算尺寸
self.titleUnderLine.xmg_width = firstbtn.titleLabel.xmg_width;
self.titleUnderLine.xmg_centerX = firstbtn.xmg_centerX;
}
#pragma mark 监听
-(void)btnClick:(UIButton *)button
{
// 如果按钮被重复点击(这次和上次点击的一样)
if (self.previousBtn == button) {
[[NSNotificationCenter defaultCenter] postNotificationName:BSTitleButtonDidRepeatClickNotification object:nil];
}
// 切换按钮状态
self.previousBtn.selected = NO;
button.selected = YES;
self.previousBtn = button;
// 下划线动画
[UIView animateWithDuration:2 animations:^{
// 处理下划线
self.titleUnderLine.xmg_width = button.titleLabel.xmg_width;
self.titleUnderLine.xmg_centerX = button.xmg_centerX;
}];
}
AllController
#import "BSAllTableViewController.h"
@interface BSAllTableViewController ()
@end
@implementation BSAllTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = BSRandomColor;
self.tableView.contentInset = UIEdgeInsetsMake(64 + 35, 0, 49, 0);
// 监听通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(titleBtnClick) name:BSTitleButtonDidRepeatClickNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tabBarClick) name:BSTabBarDidRepeatClickNotification object:nil];
}
- (void)tabBarClick
{
// if(重复点击的不是精华按钮)return
if (self.view.window == nil) return;
// if(显示在中间的不是allController)return
if (self.tableView.scrollsToTop == NO) return;
// 刷新数据
}
- (void)titleBtnClick
{
[self tabBarClick];
}
// 移除通知
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
cell.backgroundColor = [UIColor clearColor];
}
cell.textLabel.text = [NSString stringWithFormat:@"%@-%zd", self.class, indexPath.row];
return cell;
}
标题栏相关问题:
(1)
问题:标题栏不会随着ScrollView的滑动而滑动
解决:标题栏是一个UIView,将标题栏加到控制器view上,不是scrollview上。
(2)
问题:如何让下划线与按钮文字宽度相同
解决:需要先让按钮的label根据文字内容计算尺寸
(3)设置控件时,先设置宽高,在设置位置,防止控件位置不对的麻烦
(4)
问题:如何切换按钮文字颜色
解决:通过设置按钮状态来改变按钮文字颜色
(5)
问题:如何设置标题栏文字
解决:一般将所有文字放到数组中,再通过数组的i
取出
NSArray *titles = @[@"全部",@"视频",@"声音",@"图片",@"段子"];
[titleBtn setTitle:titles[i] forState:UIControlStateNormal];
(6)
问题:设置标题栏下划线颜色时,为什么最好拿到第一个按钮。
原因:设置下划线颜色与第一个标题按钮的颜色相同,当按钮颜色改变时,下划线也会随着改变,即下划线颜色和按钮颜色始终一致。
(7)
需求:希望下划线左右各+5的距离
解决:下划线的width + 10
(8)
问题:为什么要监听标题按钮和tabBar的重复点击
原因:再次点击精华或者全部等按钮时,要刷新数据
解决:利用通知,如果被重复点击了,发出通知,告诉外界按钮被点击了,在外界监听通知。
(9)
问题:被重复点击后的思路
思路:
- if(重复点击的不是精华按钮)return
if (self.view.window == nil) return;
// 当前控制器的view不在window上
- if (显示在正中间的不是AllViewController) return;
if (self.tableView.scrollsToTop == NO) return;
- 刷新数据