自定義UITableViewCell邊框

前言

在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í)就是傳入tableViewindexPath缓待,然后內(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择卦,請告訴我(__)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市背苦,隨后出現(xiàn)的幾起案子互捌,更是在濱河造成了極大的恐慌,老刑警劉巖行剂,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秕噪,死亡現(xiàn)場離奇詭異,居然都是意外死亡厚宰,警方通過查閱死者的電腦和手機(jī)腌巾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铲觉,“玉大人澈蝙,你說我怎么就攤上這事∧煊模” “怎么了灯荧?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長盐杂。 經(jīng)常有香客問我逗载,道長哆窿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任厉斟,我火速辦了婚禮挚躯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘擦秽。我一直安慰自己码荔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布感挥。 她就那樣靜靜地躺著缩搅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪链快。 梳的紋絲不亂的頭發(fā)上誉己,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天,我揣著相機(jī)與錄音域蜗,去河邊找鬼巨双。 笑死,一個(gè)胖子當(dāng)著我的面吹牛霉祸,可吹牛的內(nèi)容都是我干的筑累。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼丝蹭,長吁一口氣:“原來是場噩夢啊……” “哼慢宗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起奔穿,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤镜沽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后贱田,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缅茉,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年男摧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蔬墩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡耗拓,死狀恐怖拇颅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乔询,我是刑警寧澤樟插,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響黄锤,放射性物質(zhì)發(fā)生泄漏麻献。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一猜扮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧监婶,春花似錦旅赢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至带污,卻和暖如春僵控,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鱼冀。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工报破, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人千绪。 一個(gè)月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓充易,卻偏偏與公主長得像,于是被迫代替她去往敵國和親荸型。 傳聞我的和親對象是個(gè)殘疾皇子盹靴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容