iOS UITableView的一些琐碎

表格UITableView基本上开发中应用最常用的控件之一了,关于tableview你又了解多少呢,反正我是只知道一些常规的用法,现在把之前写过的项目中应用到的一些小细节总结一下。

cell分割线

这个不知道是不是我自己的问题,第一次遇到要将cell分割线与屏幕边缘没有间距的需求时,试了好多方法!

第一种方法

下面的这个在Objective-C里写了没有什么效果,但在Swift中可以完美执行,我不知道是不是我一个人的问题。贴出来这个方法:

1
tableView.separatorInset = UIEdgeInsetsZero;

第二种方法

这个方法是在论坛里看到的,试了试,可以的。

1
2
3
4
5
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

cell.separatorInset = UIEdgeInsetsZero;
cell.layoutMargins = UIEdgeInsetsZero;
}

tableView的这个代理方法是在cell将要出现在屏幕的时候调用。但是这种方法和第一种方法有个什么问题呢?就是不能将tableView.separatorStyle设置为UITableViewCellSeparatorStyleNone,这样就导致了如果cell的个数不足以充满屏幕的话,会在cell的底部看到空余的cell分割线,这对于我这个强迫症是不能忍的,当然了也有解决办法,就是添加一句:tableView.tableFooterView = [UIView new];就OK了。

第三种方法

自从在oc中知道第一种方法不能用之后,基本上我都在用这种方法,就是在自定义的cell里重新画线。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (void)drawRect:(CGRect)rect {

[super drawRect:rect];

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);
CGContextFillRect(context, rect);

CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:225.0/255.0 green:225.0/255.0 blue:225.0/255.0 alpha:1.0].CGColor);
CGContextStrokeRect(context, CGRectMake(0, 0, SCREEN_WIDTH, 0.5));


CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:225.0/255.0 green:225.0/255.0 blue:225.0/255.0 alpha:1.0].CGColor);
CGContextStrokeRect(context, CGRectMake(0, rect.size.height-0.5, SCREEN_WIDTH, 0.5));

}

重新绘制的话,可以设置分割线的颜色,长度,高度。

卡片式cell

就是下面这种效果:

卡片式cell

实现这种效果我已知的有三种效果:

第一种

通过设置cellcontentView来间接实现,在cellcontentView的顶部或者底部留下一定的间距,这样就会有cell间就有间距的效果。但是这种方式在cell有点击效果的时候,会很明显的看出有分层,因为这时候cell是被点击的,contentView都会有系统点击的阴影效果。这种方式在cell左滑删除,置顶等操作的时候,左滑出的视图会高出一部分(左滑显示出的高度=(cell的高度-留下的间距高度)+ 留下的间距高度),很显然这种方式有致命缺陷。

建议还是不要第一种方法

第二种

通过分组的方式间接的实现,每组的Header可以当做是cell之间的间距,每组中只有一个cell:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 

return 10;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {

return 10;

}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

return 1;

}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

return 100;

}

但是呢,这还是会出现一个问题,因为系统默认分组的时候每组的Header会停留在tableview的顶部,这要怎么处理呢?网上也有一种解决办法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { 

if (scrollView == self.tableView) {

CGFloat sectionHeaderHeight = 10;

if (scrollView.contentOffset.y <= sectionHeaderHeight && scrollView.contentOffset.y >= 0) {

scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
} else if (scrollView.contentOffset.y >= sectionHeaderHeight) {

scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
}
}
}

但是这种方式是通过scroll偏移量来监听和改变tableview的contentInset,因为只要UITableView在滚动就一直在运行,不是很好。

第三种

重写cell的setFrame方法:

1
2
3
4
5
6
7
8
- (void)setFrame:(CGRect)frame {

frame.origin.x = 15;
frame.size.width -= 2 * frame.origin.x;
frame.size.height -= 15;
frame.origin.y += 10;
[super setFrame:frame];
}

这种方式看上去很优雅,其实也有缺点,就是不适合有编辑的情况,因为在编辑的时候会不停调用setFrame方法,导致错乱,此时建议使用上面的第二种方案。

-------------本文结束感谢您的阅读-------------
分享使我快乐!