前言
在ios7之前掺喻,UITableView的UITableViewStyleGrouped style 默認(rèn)UITableViewCell有邊框的禾进。但是ios7之后蘋果主推扁平化設(shè)計(jì)風(fēng)格房揭,邊框這種擬物化的設(shè)計(jì)就不受待見了。但我們app的開發(fā)過程中智厌,總會有地方需要帶邊框的設(shè)計(jì)搜吧,所以就得自己來實(shí)現(xiàn)了√菇海基于此透典,簡單的實(shí)現(xiàn)了一下這個(gè)效果
github地址
效果圖
示例圖
我提供了一些常用的屬性進(jìn)行定制:
-
contentBorderColor
設(shè)置邊框顏色; -
contentBorderWidth
設(shè)置邊框?qū)挾龋?/li> -
contentMargin
設(shè)置左右距離屏幕邊距顿苇; -
contentBackgroundColor
設(shè)置邊框內(nèi)背景顏色峭咒; -
contentCornerRadius
設(shè)置邊框圓角;
實(shí)現(xiàn)思路
自定義一個(gè)BaseBorderCell作為基類岖圈,由它承載邊框的實(shí)現(xiàn);然后再繼承于BaseBorderCell自定義cell進(jìn)行內(nèi)容展示钙皮;
代碼展示
- BaseBorderCell.h文件
//此cell只簡單負(fù)責(zé)border的配置蜂科,cell中的內(nèi)容可以繼承于此類再進(jìn)行封裝
typedef NS_ENUM(NSUInteger, BaseCellBorderStyle) {
BaseCellBorderStyleNoRound = 0,
BaseCellBorderStyleTopRound,
BaseCellBorderStyleBottomRound,
BaseCellBorderStyleAllRound,
};
@interface BaseBorderCell : UITableViewCell
@property (nonatomic, assign) BaseCellBorderStyle borderStyle;//邊框類型
@property (nonatomic, strong) UIColor *contentBorderColor;//邊框顏色
@property (nonatomic, strong) UIColor *contentBackgroundColor;//邊框內(nèi)部內(nèi)容顏色
@property (nonatomic, assign) CGFloat contentBorderWidth;//邊框的寬度顽决,這個(gè)寬度的一半會延伸到外部,如果對寬度比較敏感的要注意下
@property (nonatomic, assign) CGFloat contentMargin;//左右距離父視圖的邊距
@property (nonatomic, assign) CGSize contentCornerRadius;//邊框的圓角
+ (instancetype)cellWithTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath;
//如果不想用上面的方法初始化cell导匣,就用下面的方法設(shè)置borderStyle
- (void)setBorderStyleWithTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath;
@end
- BaseBorderCell.m文件
#import "BaseBorderCell.h"
#define Width self.contentView.frame.size.width
#define Height self.contentView.frame.size.height
@implementation BaseBorderCell
+ (instancetype)cellWithTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath
{
BaseBorderCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell = [[BaseBorderCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}
//一定要這里設(shè)置style才菠,而不能在上面的判斷里面,因?yàn)閏ell重用的時(shí)候贡定,只要有不同的地方都應(yīng)該重新設(shè)置赋访,否則拿到cell的style就是上一個(gè)的樣式而自己卻沒有進(jìn)行修改
if (indexPath.row == 0 && indexPath.row == [tableView numberOfRowsInSection:indexPath.section] - 1) {
cell.borderStyle = BaseCellBorderStyleAllRound;
}else if (indexPath.row == 0) {
cell.borderStyle = BaseCellBorderStyleTopRound;
}else if (indexPath.row == [tableView numberOfRowsInSection:indexPath.section] - 1) {
cell.borderStyle = BaseCellBorderStyleBottomRound;
}else {
cell.borderStyle = BaseCellBorderStyleNoRound;
}
return cell;
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//配置默認(rèn)值
self.contentBorderColor = [UIColor lightGrayColor];
self.contentBackgroundColor = [UIColor whiteColor];
self.contentBorderWidth = 2.0;
self.contentMargin = 10.0;
self.contentCornerRadius = CGSizeMake(5, 5);
}
return self;
}
- (void)setBorderStyleWithTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0 && indexPath.row == [tableView numberOfRowsInSection:indexPath.section] - 1) {
self.borderStyle = BaseCellBorderStyleAllRound;
}else if (indexPath.row == 0) {
self.borderStyle = BaseCellBorderStyleTopRound;
}else if (indexPath.row == [tableView numberOfRowsInSection:indexPath.section] - 1) {
self.borderStyle = BaseCellBorderStyleBottomRound;
}else {
self.borderStyle = BaseCellBorderStyleNoRound;
}
}
- (void)layoutSubviews
{
[super layoutSubviews];
//在這里設(shè)置才能獲取到真正顯示時(shí)候的寬度,而不是原始的
[self setupBorder];
}
- (void)setupBorder
{
self.selectionStyle = UITableViewCellSelectionStyleNone;
self.backgroundColor = [UIColor clearColor];
CAShapeLayer *layer = [CAShapeLayer layer];
layer.lineWidth = self.contentBorderWidth;
layer.strokeColor = self.contentBorderColor.CGColor;
layer.fillColor = self.contentBackgroundColor.CGColor;
UIView *view = [[UIView alloc] initWithFrame:self.contentView.bounds];
[view.layer insertSublayer:layer atIndex:0];
view.backgroundColor = [UIColor clearColor];
//用自定義的view代替cell的backgroundView
self.backgroundView = view;
CGRect rect = CGRectMake(self.contentMargin, 0, Width - 2*self.contentMargin, Height);
switch (self.borderStyle) {
case BaseCellBorderStyleNoRound:
{
UIBezierPath *path = [UIBezierPath bezierPathWithRect:rect];
layer.path = path.CGPath;
}
break;
case BaseCellBorderStyleTopRound:
{
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:self.contentCornerRadius];
layer.path = path.CGPath;
}
break;
case BaseCellBorderStyleBottomRound:
{
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:self.contentCornerRadius];
layer.path = path.CGPath;
}
break;
case BaseCellBorderStyleAllRound:
{
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:self.contentCornerRadius];
layer.path = path.CGPath;
}
break;
default:
break;
}
}
@end
其實(shí)就是傳入tableView
和indexPath
缓待,然后內(nèi)部判斷當(dāng)前cell應(yīng)該用那種borderStyle
展示蚓耽;接著用UIBezierPath
畫出來,通過CAShapeLayer
展示出來旋炒。需要注意的細(xì)節(jié)就是用自定義的view
來替代backgroundView
步悠。
如何使用
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
/*
你可以使用自己的初始化方法
BaseBorderCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell = [[BaseBorderCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}
[cell setBorderStyleWithTableView:tableView indexPath:indexPath];
*/
//也可以這樣子
BaseBorderCell *cell = [BaseBorderCell cellWithTableView:tableView indexPath:indexPath];
cell.contentBorderColor = COLOR_WITH_HEX(0x816973, 1);
cell.contentBackgroundColor = COLOR_WITH_HEX(0xe6d8be, 1);
cell.contentBorderWidth = 2.0;
cell.contentMargin = 10;
cell.contentCornerRadius = CGSizeMake(5, 5);
cell.textLabel.text = [NSString stringWithFormat:@"section%ld--index%ld",(long)indexPath.section,(long)indexPath.row];
return cell;
}
寫在最后
此文僅在提供一種實(shí)現(xiàn)邊框cell的基本思路,盡可能少的依賴外部參數(shù)來確定cell的邊框樣式瘫镇,然后盡可能人性化的設(shè)置邊框的屬性鼎兽;作為一個(gè)基類的cell繼承它就能使用邊框的特性。
此上所言铣除,僅為個(gè)人想法谚咬,如果有什么錯(cuò)誤的地方,麻煩各位大神指針尚粘;如有更好的思路或demo择卦,請告訴我(__)