之前项目需要,做过类似篮球比赛技术统计的功能。大家都知道,每只队伍有10多个球员,技术统计会包括:姓名、得分、篮板、助攻、盖帽、2分投篮、3分投篮、罚球……大概效果就类似Excel要做的。但是手机屏幕宽度有限,所以左右滑动成了一个需求。同时,为了保证滑动过程中也能直接明了的对上号,所以第一列姓名理应保持不动。
- 首列固定
- 向左滑动查看更多列
- 上拉刷新、下拉加载更多
代码块
1、宏定义
#define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
#define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
#define BPCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0]
#define BackgroundColor BPCOLOR(239, 239, 239)
#define BPClearColor [UIColor clearColor]
#define BPWhiteColor [UIColor whiteColor]
#define BPRedColor [UIColor redColor]
#define kNavHeight 64
#define kHeaderHeight 49
#define kCellHeight 60
2、基本控件-属性
@interface ViewController ()<UIScrollViewDelegate,UITableViewDelegate,UITableViewDataSource>
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UITableView *leftTableView;
@property (nonatomic, strong) UITableView *rightTableView;
@property (nonatomic, strong) UIView *leftHeaderView;
@property (nonatomic, strong) UIView *rightHeaderView;
@property (nonatomic, strong) NSMutableArray *dataArr;
@property (nonatomic, strong) NSMutableArray *tempArr;
@property (nonatomic, assign) NSInteger pageNum;
@end
3、viewDidLoad
self.title = @"TableView";
self.view.backgroundColor = BackgroundColor;
self.automaticallyAdjustsScrollViewInsets = NO;
/**
* scrollView
*/
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, kNavHeight, SCREEN_WIDTH, SCREEN_HEIGHT-kNavHeight)];
_scrollView.bounces = NO; // 反弹
_scrollView.backgroundColor = BPWhiteColor;
_scrollView.scrollEnabled = YES;
_scrollView.delegate = self;
[self.view addSubview:_scrollView];
/**
* rightHeaderView
*/
_rightHeaderView = [[UIView alloc] initWithFrame:CGRectMake(SCREEN_WIDTH / 3, 0, SCREEN_WIDTH , kHeaderHeight)];
_rightHeaderView.backgroundColor = BPWhiteColor;
UILabel *rightLabel1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH/3, kHeaderHeight)];
rightLabel1.text = @"Right1";
rightLabel1.textColor = BPRedColor;
rightLabel1.textAlignment = NSTextAlignmentCenter;
[_rightHeaderView addSubview:rightLabel1];
UILabel *rightLabel2 = [[UILabel alloc] initWithFrame:CGRectMake(SCREEN_WIDTH/3, 0, SCREEN_WIDTH/3, kHeaderHeight)];
rightLabel2.text = @"Right2";
rightLabel2.textColor = BPRedColor;
rightLabel2.textAlignment = NSTextAlignmentCenter;
[_rightHeaderView addSubview:rightLabel2];
UILabel *rightLabel3 = [[UILabel alloc] initWithFrame:CGRectMake(SCREEN_WIDTH/3 * 2, 0, SCREEN_WIDTH/3, kHeaderHeight)];
rightLabel3.text = @"Right3";
rightLabel3.textColor = BPRedColor;
rightLabel3.textAlignment = NSTextAlignmentCenter;
[_rightHeaderView addSubview:rightLabel3];
UIView *lineView1 = [[UIView alloc] initWithFrame:CGRectMake(0, kHeaderHeight-1, _rightHeaderView.width, 1)];
lineView1.backgroundColor = BPCOLOR(217, 217, 217);
[_rightHeaderView addSubview:lineView1];
/**
* rightTableView
*/
_rightTableView = [[UITableView alloc] initWithFrame:CGRectMake(_rightHeaderView.x, 0, _rightHeaderView.width, _scrollView.height) style:UITableViewStylePlain];
_rightTableView.delegate = self;
_rightTableView.dataSource = self;
_rightTableView.backgroundColor = BPClearColor;
_rightTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_rightTableView.showsVerticalScrollIndicator = NO;
[_scrollView addSubview:_rightTableView];
/**
* leftHeaderView
*/
_leftHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, kHeaderHeight)];
_leftHeaderView.backgroundColor = BPClearColor;
UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH / 3, kHeaderHeight)];
tempView.backgroundColor = BPWhiteColor;
[_leftHeaderView addSubview:tempView];
UILabel *leftLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, kHeaderHeight)];
leftLabel.text = @"Left";
leftLabel.textColor = BPRedColor;
[_leftHeaderView addSubview:leftLabel];
UIView *lineView2 = [[UIView alloc] initWithFrame:CGRectMake(0, kHeaderHeight-1, tempView.width, 1)];
lineView2.backgroundColor = BPCOLOR(217, 217, 217);
[tempView addSubview:lineView2];
/**
* leftTableView
*/
_leftTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, _scrollView.height) style:UITableViewStylePlain];
_leftTableView.delegate = self;
_leftTableView.dataSource = self;
_leftTableView.backgroundColor = BPClearColor;
_leftTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_leftTableView.showsVerticalScrollIndicator = NO;
[_scrollView addSubview:_leftTableView];
_scrollView.contentSize = CGSizeMake(SCREEN_WIDTH / 3 * 4, _scrollView.height);
[self setupRefresh];
4、刷新
- (void)setupRefresh
{
self.leftTableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNew)];
self.leftTableView.mj_header.automaticallyChangeAlpha = YES;
[self.leftTableView.mj_header beginRefreshing];
self.leftTableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMore)];
}
逻辑
1、底层为一个屏幕大小的UIScrollerView;
2、rightTableView 加到UIScrollerView之上,需要注意的是它的.X和width.(leftTableView上固定的第一列的宽度就是rightTableView的x, 右边总共列数X列宽)。
3、leftTableView。leftTableView的width=屏幕宽度。之所以后加它到UIScrollerView上且宽度为屏幕宽度,是因为我们的上拉下拉刷新控件都由它来处理。宽度为屏幕宽度,那么就会盖住rightTableView了吧?没关系,有个属性:backgroundColor, 把设置 leftTableView,以及leftTableView的cell的backgroundColor设置为ClearColor;那么rightTableView就不会被盖住啦。 当然,leftTableView左边还有一列。在leftTableView的cell上自定义一个一定宽度的UIView就可以啦。
4、然后就是给leftTableView添加上拉下拉的刷新控件了。直接用MJRefresh,简单粗暴!
5、最重要的地方 - UIScrollerView Delegate
// leftTableView与rightTableView 上下滚动同步
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (self.leftTableView == scrollView) {
[self.rightTableView setContentOffset:self.leftTableView.contentOffset];
} else if (self.rightTableView == scrollView) {
[self.leftTableView setContentOffset:self.rightTableView.contentOffset];
} else if (self.rightScrollView == scrollView) {
CGFloat contentXoffset = scrollView.contentOffset.x;
self.leftTableView.x = contentXoffset;
}
}
leftTableView和rightTableView上下滚动同步,同时左右滑动scrollView,leftTableView.x随着scrollView的偏移量改变而改变,致使看上去水平方向它始终固定不动。
整个来讲,其实是为了达到目的不折手段。也看到在其他ipad项目里有更加屌爆的效果,可是找不到更有用的源码。之所以如此折腾还要搞成透明不透明的,最重要的一个原因就是刷新控件。
第一次写这玩意,请包涵。