TableviewCell section 高性能切圓角加陰影

運(yùn)用shapeLayer 和 貝塞爾曲線 繪制圓角和陰影


- (void)tableView:(UITableView*)tableView willDisplayCell:(UITableViewCell*)cell forRowAtIndexPath:(NSIndexPath*)indexPath{

// 圓角弧度半徑

? ? CGFloatcornerRadius =5.f;

? ? // 設(shè)置cell的背景色為透明,如果不設(shè)置這個(gè)的話,則原來(lái)的背景色不會(huì)被覆蓋

? ? self.backgroundColor = UIColor.clearColor;

? ? // 創(chuàng)建一個(gè)shapeLayer

? ? CAShapeLayer *layer = [[CAShapeLayer alloc] init];

? ? CAShapeLayer *backgroundLayer = [[CAShapeLayer alloc] init]; //顯示選中

? ? // 創(chuàng)建一個(gè)可變的圖像Path句柄,該路徑用于保存繪圖信息

? ? CGMutablePathRef pathRef = CGPathCreateMutable();

? ? // 獲取cell的size

? ? // 第一個(gè)參數(shù),是整個(gè) cell 的 bounds, 第二個(gè)參數(shù)是距左右兩端的距離,第三個(gè)參數(shù)是距上下兩端的距離

? ? CGRect bounds = CGRectInset(self.bounds, 20, 0);

if(indexPath.row==0) {//第一個(gè)cell

? ? ? ? if([tableViewnumberOfRowsInSection:indexPath.section] ==1) {//section 只有一個(gè)cell

? ? ? ? ? ? CGPathMoveToPoint(pathRef,nil,CGRectGetMinX(bounds),CGRectGetMaxY(bounds));

? ? ? ? ? ? CGPathAddArcToPoint(pathRef,nil,CGRectGetMinX(bounds),CGRectGetMinY(bounds),CGRectGetMidX(bounds),CGRectGetMinY(bounds), cornerRadius);

? ? ? ? ? ? CGPathAddArcToPoint(pathRef,nil,CGRectGetMaxX(bounds),CGRectGetMinY(bounds),CGRectGetMaxX(bounds),CGRectGetMidY(bounds), cornerRadius);

? ? ? ? ? ? CGPathAddArcToPoint(pathRef,nil,CGRectGetMaxX(bounds),CGRectGetMaxY(bounds),CGRectGetMidX(bounds),CGRectGetMaxY(bounds), cornerRadius);

? ? ? ? ? ? CGPathAddArcToPoint(pathRef,nil,CGRectGetMinX(bounds),CGRectGetMaxY(bounds),CGRectGetMinX(bounds),CGRectGetMidY(bounds), cornerRadius);

? ? ? ? ? ? CGPathAddLineToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMaxY(bounds));


? ? ? ? }else{

? ? ? ? ? ? // 初始起點(diǎn)為cell的左下角坐標(biāo)

? ? ? ? ? ? CGPathMoveToPoint(pathRef,nil,CGRectGetMinX(bounds),CGRectGetMaxY(bounds));

? ? ? ? ? ? CGPathAddArcToPoint(pathRef,nil,CGRectGetMinX(bounds),CGRectGetMinY(bounds),CGRectGetMidX(bounds),CGRectGetMinY(bounds), cornerRadius);

? ? ? ? ? ? CGPathAddArcToPoint(pathRef,nil,CGRectGetMaxX(bounds),CGRectGetMinY(bounds),CGRectGetMaxX(bounds),CGRectGetMidY(bounds), cornerRadius);

? ? ? ? ? ? // 終點(diǎn)坐標(biāo)為右下角坐標(biāo)點(diǎn),把繪圖信息都放到路徑中去,根據(jù)這些路徑就構(gòu)成了一塊區(qū)域了

? ? ? ? ? ? CGPathAddLineToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds));

? ? ? ? }

? ? }elseif(indexPath.row== [tableViewnumberOfRowsInSection:indexPath.section]-1) {//最后一個(gè)cell

? ? ? ? // 初始起點(diǎn)為cell的左上角坐標(biāo)

? ? ? ? CGPathMoveToPoint(pathRef, nil, CGRectGetMinX(bounds), CGRectGetMinY(bounds));

? ? ? ? CGPathAddArcToPoint(pathRef,nil,CGRectGetMinX(bounds),CGRectGetMaxY(bounds),CGRectGetMidX(bounds),CGRectGetMaxY(bounds), cornerRadius);

? ? ? ? CGPathAddArcToPoint(pathRef,nil,CGRectGetMaxX(bounds),CGRectGetMaxY(bounds),CGRectGetMaxX(bounds),CGRectGetMidY(bounds), cornerRadius);

? ? ? ? // 添加一條直線,終點(diǎn)坐標(biāo)為右下角坐標(biāo)點(diǎn)并放到路徑中去

? ? ? ? CGPathAddLineToPoint(pathRef, nil, CGRectGetMaxX(bounds), CGRectGetMinY(bounds));

? ? }else{


? ? ? ? // 添加cell的rectangle信息到path中(不包括圓角)

? ? ? ? CGPathAddRect(pathRef,nil, bounds);

? ? }



? ? // 把已經(jīng)繪制好的可變圖像路徑賦值給圖層,然后圖層根據(jù)這圖像path進(jìn)行圖像渲染render

? ? layer.path= pathRef;

? ? backgroundLayer.path= pathRef;

? ? // 注意:但凡通過(guò)Quartz2D中帶有creat/copy/retain方法創(chuàng)建出來(lái)的值都必須要釋放

? ? CFRelease(pathRef);

? ? // 按照shape layer的path填充顏色,類似于渲染render

? ? // layer.fillColor = [UIColor colorWithWhite:1.f alpha:0.8f].CGColor;

? ? layer.fillColor = [UIColor whiteColor].CGColor;




? ? // view大小與cell一致

? ? UIView*roundView = [[UIViewalloc]initWithFrame:bounds];

? ? // 添加自定義圓角后的圖層到roundView中

? ? [roundView.layer insertSublayer:layer atIndex:0];

? ? roundView.backgroundColor = UIColor.clearColor;

? ? // cell的背景view

? ? self.backgroundView= roundView;


? ??// 給section加陰影

? ? BOOLisFirstRow = !indexPath.row;// 第一個(gè)cell

? ? BOOLisLastRow = (indexPath.row== [tableViewnumberOfRowsInSection:indexPath.section] -1);//最后一個(gè)cell

? ? BOOLisSectionOneRow = ([tableViewnumberOfRowsInSection:indexPath.section] ==1);// 只有一個(gè)cell

? ? // the shadow rect determines the area in which the shadow gets drawn

? ? CGRect shadowRect = CGRectInset(CGRectMake(0, 0, kScreen_Width, self.frame.size.height), 20, -10);

? ? if(isFirstRow)

?? ? ? shadowRect.origin.y+=10;

? ? elseif(isLastRow)

? ? ? ? shadowRect.size.height-=10;

? ? // the mask rect ensures that the shadow doesn't bleed into other table cells

? ? CGRect maskRect = CGRectInset(CGRectMake(0, 0, kScreen_Width, self.frame.size.height), -20, 0);

? ? if(isFirstRow) {

? ? ? ? maskRect.origin.y-=10;

? ? ? ? maskRect.size.height+=10;

? ? }

? ? elseif(isLastRow)

? ? ? ? maskRect.size.height+=10;


? ? // 如果section 只有一個(gè)cell

? ? if(isSectionOneRow) {

? ? ? ? for(inti =0; i <2; i++) {

? ? ? ? shadowRect.size.height-=10;

? ? ? ? maskRect.size.height+=2.5;

? ? ? ? }


? ? }


? ? // now configure the background view layer with the shadow

? ? CALayer *layers = self.backgroundView.layer;

? ? layers.shadowColor = SecondTextColor.CGColor;

? ? layers.shadowOffset = CGSizeMake(0, 0);

? ? layers.shadowRadius=2.5;

? ? layers.shadowOpacity=0.2f;

? ? layers.shadowPath = [UIBezierPath bezierPathWithRoundedRect:shadowRect cornerRadius:5].CGPath;

? ? layers.masksToBounds=NO;

? ? // and finally add the shadow mask

? ? CAShapeLayer *maskLayer = [CAShapeLayer layer];

? ? maskLayer.path = [UIBezierPath bezierPathWithRect:maskRect].CGPath;

? ? layers.mask= maskLayer;

}

為了減少代碼寫了一個(gè)分類直接導(dǎo)入項(xiàng)目,

[cell addShadowToSectionTableView:tableView atIndexPath:indexPath];

?[cell addShadowToCellInTableView:tableView atIndexPath:indexPath];

代碼地址:?https://github.com/WWally/CSTableViewCell

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容