在做项目时,遇到两次这样的界面:上部是按钮栏,按钮下面有随意滑动的指示线,下面很多界面可以左右滑动来切换,线条也会随着界面滑动而滑动。
于是我把之前做的优化了一下,变得更容易添加按钮和界面
大体思路是将一个个tableView添加到scrollView中,扩大scrollView的滚动范围,根据scrollView的contentOffset属性判断滚到哪个视图,从而改变按钮状态(selected还是normal)和指示线的位置。
直接上代码:
ViewController.h
#define Width self.view.frame.size.width
#define Height self.view.frame.size.height
#import <UIKit/UIKit.h>
#import "TitleView.h"
@interface ViewController : UIViewController
//按钮栏
@property(nonatomic,strong)TitleView *titleView;
@property(nonatomic,strong)UIScrollView *scrollView;
//添加多少个tableView
- (void)addTableViewWithNumber:(NSInteger)number;
//按钮点击事件
- (void)btnClick:(UIButton *)btn;
//添加指示线
- (void)addLine;
@end
ViewController.m
#import "ViewController.h"
@interface ViewController ()<UITableViewDataSource,UITableViewDelegate,UIScrollViewDelegate>
//目前被选中的按钮
@property(nonatomic,strong)UIButton *selectedBtn;
//指示线
@property(nonatomic,strong)UIView *lineView;
//存放数据的数组
@property(nonatomic,strong)NSMutableArray *cellData;
//标题按钮栏数组
@property(nonatomic,strong)NSMutableArray *titleArray;
@end
@implementation ViewController
//添加scrollView
- (UIScrollView *)scrollView{
if (_scrollView == nil) {
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(_titleView.frame), Width, Height - 50)];
_scrollView.delegate = self;
_scrollView.pagingEnabled = YES;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.bounces = NO;
}
return _scrollView;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
//按钮点击事件
- (void)btnClick:(UIButton *)btn{
_selectedBtn.selected = NO;
_selectedBtn = btn;
_selectedBtn.selected = YES;
[UIView animateWithDuration:0.5 animations:^{
_scrollView.contentOffset = CGPointMake(btn.tag * Width, 0);
}];
}
//根据标题按钮的数目添加tableView
- (void)addTableViewWithNumber:(NSInteger)number{
for (int i = 0; i < number; i++) {
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(i*Width, 0, Width, Height - CGRectGetMaxY(_titleView.frame)) style:UITableViewStylePlain];
tableView.tag = i;
tableView.delegate = self;
tableView.dataSource = self;
[_scrollView addSubview:tableView];
}
}
//添加指示线
- (void)addLine
{
UIView *blackLine = [[UIView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(_titleView.frame), Width, 1)];
blackLine.backgroundColor = [UIColor colorWithRed:220/255.0 green:220/255.0 blue:223/255.0 alpha:1];
[self.view addSubview:blackLine];
_lineView = [[UIView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(_titleView.frame), Width/_titleView.subviews.count, 2)];
_lineView.backgroundColor = [UIColor orangeColor];
[self.view addSubview:_lineView];
}
//监听scrollView的滚动事件
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
//由于tableView继承自scrollVeiw,tableView滚动时也会触发此方法,故需判断是否为scrollView
if (scrollView == _scrollView) {
if (scrollView == _scrollView) {
double x = scrollView.contentOffset.x *(1.0/_titleView.subviews.count);
//设置线条位置
_lineView.frame = CGRectMake(x, CGRectGetMaxY(_titleView.frame), Width/_titleView.subviews.count, 2);
NSInteger index = (scrollView.contentOffset.x+Width/2)/Width;
_selectedBtn.selected = NO;
_selectedBtn = _titleView.subviews[index];
_selectedBtn.selected = YES;
}
}
}
//tableView数据源代理方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSMutableArray *array;
for (int i = 0; i < _scrollView.subviews.count; i++) {
if (tableView == _scrollView.subviews[i]) {
array = _cellData[i];
}
}
return array.count;
}
- (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.textLabel.text = @"ewlifhyioew";
}
return cell;
}
@end
TitleView.h
#import <UIKit/UIKit.h>
@interface TitleView : UIView
-(instancetype)initWithTitleArray:(NSMutableArray *)array frame:(CGRect)frame;
@end
TitleView.m
自定义titleView也就是标题按钮栏
#define Width self.frame.size.width
#define Height self.frame.size.height
#import "TitleView.h"
@implementation TitleView
-(instancetype)initWithTitleArray:(NSMutableArray *)array frame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
CGFloat btnWidth = Width/array.count;
for(int i = 0;i<array.count;i++){
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(i*btnWidth, 0, btnWidth, Height)];
[btn setTitle:array[i] forState:UIControlStateNormal];
[btn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
[btn setTitleColor:[UIColor orangeColor] forState:UIControlStateSelected];
btn.tag = i;
[self addSubview:btn];
}
}
return self;
}
@end
以上为父类代码,若要使用,需继承然后在子类控制器中ViewDidLoad方法添加以下代码
- (void)viewDidLoad {
[super viewDidLoad];
//初始化title数组,创建titleView
NSMutableArray *array = [NSMutableArray arrayWithArray:@[@"全部",@"好评",@"中评",@"差评"]];
self.titleView = [[TitleView alloc] initWithTitleArray:array frame:CGRectMake(0, 0, Width, 50)];
[self.view addSubview:self.titleView];
//遍历按钮,为其添加事件
for (int i = 0; i < self.titleView.subviews.count; i++) {
UIButton *btn = self.titleView.subviews[i];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
}
//调用父类方法
[self.view addSubview:self.scrollView];
//设置scrollView滚动范围
self.scrollView.contentSize = CGSizeMake(array.count*Width, Height);
//添加tableView
[self addTableViewWithNumber:array.count];
//设置第一个点击按钮
[self btnClick:self.titleView.subviews[0]];
//添加滑动线条
[self addLine];
}
关于tableView中的数据根据模型来创建cell,然后在cellData数组中再添加含有tableView数据的数组,根据tableView的tag不同,可取到自己的数据
这里不做测试
自己感觉使用方法较为复杂,待日后优化。