運(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