我們繼續上面那篇來,在實現了頭部圖片下拉縱向拉伸效果後,緊接着就是這個頁面的核心,當前進度佔總進度的比例效果顯示。按照我的需求就是下面這個圖的樣子。
左側進度和右側進度說明整體被封裝在一個自定義的TableViewCell裏,如下圖所示。
爲了方便控制,我在寫的時候把這個自定義cell分爲了左右兩部分,即左面白色背景部分和右面灰色背景部分。右面灰色背景部分就是普通的空間堆疊,這裏不具體闡述,接下來我們講一下左面進度的實現。
這裏我採用的是UIView.layer addSublayer的方式。所以這裏我做了兩個重疊的UIView,分別用來顯示灰色的總體進度以及綠色的實際進度。由於需要多次進行線段的繪製,因此在這裏要封裝一個繪製線段的方法,如下:
/**
* 通過 CAShapeLayer方式繪製虛線
*
* param lineView: 需要繪製成虛線的view
* param lineLength: 虛線的寬度
* param lineSpacing: 虛線的間距
* param lineColor: 虛線的顏色
**/
- (void)drawLineOfDashByCAShapeLayer:(UIView *)lineView lineLength:(int)lineLength lineSpacing:(int)lineSpacing lineColor:(UIColor *)lineColor {
CGRect rect = CGRectMake(0, 0, 1, CGRectGetHeight(lineView.frame));
UIBezierPath *path = [UIBezierPath bezierPathWithRect:rect];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.strokeColor = lineColor.CGColor;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.lineWidth = CGRectGetWidth(lineView.frame);
shapeLayer.lineJoin = kCALineJoinRound;
shapeLayer.lineCap = kCALineCapRound;
shapeLayer.path = path.CGPath;
shapeLayer.lineDashPattern = @[[NSNumber numberWithInt:lineLength], [NSNumber numberWithInt:lineSpacing]];//畫虛線
[lineView.layer addSublayer:shapeLayer];
}
因此,當左面區域初始化的時候,代碼可以這樣寫:
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(20, 0, WIDTH/5-20, 100)];
[self.contentView addSubview:leftView];
guijiImageView = [[UIImageView alloc] initWithFrame:CGRectMake(leftView.frame.size.width/2-10, 0, 20, 20)];//界面上圓形閃電裝的節點圖標
[guijiImageView setImage:[UIImage imageNamed:@"guiji_gray"]];
[guijiImageView setAlpha:0.3];
[leftView addSubview:guijiImageView];
lineView = [[UIView alloc] initWithFrame:CGRectMake(leftView.frame.size.width/2-1, 20, 2, leftView.frame.size.height-20)];//默認的下層灰色虛線部分(也包括了完整的顯示在一個cell裏的綠色實線)
[leftView addSubview:lineView];
[self drawLineOfDashByCAShapeLayer:lineView lineLength:3 lineSpacing:4 lineColor:[UIColor lightGrayColor]];//繪製下層灰色虛線
[lineView setAlpha:0.3];
cutLineView = [[UIView alloc] initWithFrame:CGRectMake(leftView.frame.size.width/2-1, 20, 2, leftView.frame.size.height-20)];//沒有完整的顯示在一個cell裏的帶圓形終點的綠色實線
[leftView addSubview:cutLineView];
此時界面如下。
接下來繪製能夠完整的顯示在一個階段的綠色實線。這裏還是調用之前封裝好的繪製線段的方法,不同的是在傳參的時候要注意lineLength和lineSpacing兩個參數,如下:
[self drawLineOfDashByCAShapeLayer:lineView lineLength:1 lineSpacing:1 lineColor:[UIColor colorWithRed:15/255.0 green:184/255.0 blue:110/255.0 alpha:1]];
此時界面如下圖所示。
然後繪製當沒有完整的貫穿整個階段的帶有圓形終點的實線。此時就要用上之前我們定義過的cutLineView,以及爲了方便,我們再次封裝一個專門用來繪製此類線段的放下,見下方代碼。
- (void)drawLineOfDashAndCircleByCAShapeLayer:(UIView *)lineView lineLength:(int)lineLength lineSpacing:(int)lineSpacing lineColor:(UIColor *)lineColor {
CGRect rect = CGRectMake(0, 0, 1, CGRectGetHeight(lineView.frame)-10);
UIBezierPath *path = [UIBezierPath bezierPathWithRect:rect];
[path moveToPoint:CGPointMake(0, CGRectGetHeight(lineView.frame))];
[path addArcWithCenter:CGPointMake(0, CGRectGetHeight(lineView.frame)-5) radius:5 startAngle:M_PI_2 endAngle:M_PI*3.f clockwise:YES];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.strokeColor = lineColor.CGColor;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.lineWidth = CGRectGetWidth(lineView.frame);
shapeLayer.lineJoin = kCALineJoinRound;
shapeLayer.lineCap = kCALineCapRound;
shapeLayer.path = path.CGPath;
[lineView.layer addSublayer:shapeLayer];
CGRect circleRect = CGRectMake(0-2.5, CGRectGetHeight(lineView.frame)-7.5, 5, 5);
path = [UIBezierPath bezierPathWithRect:circleRect];
CAShapeLayer *shapeCircleLayer = [CAShapeLayer layer];
shapeCircleLayer.strokeColor = [UIColor whiteColor].CGColor;
shapeCircleLayer.fillColor = [UIColor whiteColor].CGColor;
shapeCircleLayer.path = path.CGPath;
[lineView.layer addSublayer:shapeCircleLayer];
}
上面這個方法實際上是在第一個基礎方法之上,在UIView上add兩個sublayer組合而成,分別爲含有空心圓圈的實線,以及填補空心圓圈爲實心圓圈的填充部分。
含有空閒圓圈的實線繪製利用UIBezierPath的moveToPoint方法在繪製實線後將筆觸移動到繪製圓形的起點,然後利用- (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise 方法繪製指定的弧線組成一個圓環。
這時候界面就會變成下圖所示:
最後我們針對最後一個cell進行虛線消除和如果進度全部完成時點亮最後一個cell上閃電圖案操作。我這裏僅僅是把灰色的虛線置爲和背景相同的顏色以及將閃電圖案變更就達到了想要的效果。
這樣,我們的自定義Cell就完成了。
在調用這個自定義cell的時候需要注意TableViewCell的重用問題,所以關於判斷顯示的代碼要寫在cellForRowAtIndexPath方法中的if (cell==nil) 判斷內,否則在滑動tableView的時候,cell會進行重置,最主要的後果就是在繪製帶有圓形終點的實線時,會上下隨着滑動繪製多個在界面。