
需求: 实现一张列表, 左边的侧边栏固定,右边能够上下左右滑动, 能够点击某一行, 进入下一个界面,伴随有点击的高亮效果。
如果没有点击的效果, 那我们很容易会联想到的是collectionView,通过重写他的UICollectionViewLayout中的- (void)prepareLayout
等方法来实现。而今天我实现这种布局的方法用的是两个tableView, 一个scrollView。scrollView可以上下左右滑动,能够实现右侧的左右滑动的效果;tableView则能够实现页面的布局。
1.布局
首先在左侧铺建了一个tableView, 这个tableView的头视图就是上面gif图中的‘统计’。而右侧的tableView首先是添加在scrollView上面的。这个scrollView的宽度由有多少列决定的。tableView 的宽度和scrollView的宽度相同, 高度相同。tableView的头视图就是gif图里面, ‘A级, B级’的那个。这里的tableView都是采用的UITableViewStylePlain。
2.关联tableView的上下左右滑动
设置scrollView的滑动方向是水平的,所以tableView看上去就能够左右滑动了, 这也是为什么tableView的宽度和scrollView的宽度一致。 而竖直方向上面的滑动逻辑, 就让tableView去处理。
tableView继承于UIScrollView,所以这两个tableView都能在滑动的时候触发的方法有- (void)scrollViewDidScroll:(UIScrollView *)scrollView
,目的是为了在左侧的tableView上下滑动的时候,右侧跟随滑动; 右侧的tableView滑动的时候, 左侧的跟随滑动。 在这个方法里面实现关联的逻辑:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView == self.rightTableView) {
if (self.leftTableView.contentOffset.y != self.rightTableView.contentOffset.y) {
self.leftTableView.contentOffset = CGPointMake(0, self.rightTableView.contentOffset.y);
}
} else if (scrollView == self.leftTableView) {
if (self.rightTableView.contentOffset.y != self.leftTableView.contentOffset.y) {
self.rightTableView.contentOffset = CGPointMake(self.rightTableView.contentOffset.x, self.leftTableView.contentOffset.y);
}
}
}
3.点击效果
点击的时候, 两个tableView的效果要同时出现,而didSelectRowAtIndexPath
方法是自动调用的,为了实现平时的那种点击tableView时候的deselectRowAtIndexPath
的效果,能够联想到了didHighlightRowAtIndexPath和didUnhighlightRowAtIndexPath方法。于是可以用这三个方法实现行高亮,代码如下:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == _leftTableView || tableView == _rightTableView) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self changeTableViewCellBackgroundColor:NO indexPath:indexPath];
});
}
}
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == _leftTableView || tableView == _rightTableView) {
[self changeTableViewCellBackgroundColor:YES indexPath:indexPath];
}
}
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == _leftTableView || tableView == _rightTableView) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self changeTableViewCellBackgroundColor:NO indexPath:indexPath];
});
[self didSelectTableViewCell:tableView indexPath:indexPath];
}
}
/// cell点击事件
- (void)didSelectTableViewCell:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath
{
}
- (void)changeTableViewCellBackgroundColor:(BOOL)change indexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell1 = [_leftTableView cellForRowAtIndexPath:indexPath];
UITableViewCell *cell2 = [_rightTableView cellForRowAtIndexPath:indexPath];
if (change) {
cell1.backgroundColor = SelectColor;
cell2.backgroundColor = SelectColor;
} else {
[UIView animateWithDuration:.2 animations:^{
cell1.backgroundColor = ColorWhite;
cell2.backgroundColor = ColorWhite;
}];
}
}
注意:tableViewCell要设置:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
4.右侧的tableViewCell里面的布局
需要按照返回数据提供的列数来创建label。于是,在传值的方法里面, 创建label; 如果label已经存在, 就不再创建,直接赋值。
示例代码如下:
- (void)configureWithItem:(id)item
{
NSArray *datas = item;
CGFloat widthForItem = 100;
CGFloat heightForItem = 50;
UILabel *label = [self viewWithTag:100];
if (label == NULL) {
for (NSInteger i = 0 ; i < datas.count; i++) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(widthForItem * i, 0, widthForItem, heightForItem - 3)];
label.textAlignment = NSTextAlignmentCenter;
label.numberOfLines = 2;
label.text = datas[i];
label.tag = 100 + i;
[self addSubview:label];
}
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, heightForItem - .5, widthForItem * datas.count, .5)];
lineView.backgroundColor = ColorTableSeparator;
[self.contentView addSubview:lineView];
} else {
for (int i = 0; i < datas.count; i++) {
UILabel *label = [self viewWithTag:100 + i];
label.text = datas[i];
}
}
}
本文提供的是一种思路, 如果有更好的思路, 希望能够在评论区提出来, 共同进步。 谢谢。
网友评论