一者冤、半圓弧型滑塊的設(shè)計
最近項目中需要用到半圓弧形滑塊,其作用和UISlider差不多档痪,用于拖動改變播放音樂的播放進度涉枫。
大概樣子是這樣的:
特點如下:
滑動響應(yīng)區(qū)域為弧環(huán)上,并且靠近滑動塊腐螟,愿汰,并限制了中心區(qū)域不可滑動;
當值為0時不可再逆時針滑動遭垛,當值為最大值時尼桶,不再可順時針滑動。
最后我自己設(shè)計一個功能锯仪,可以按固定值隨意跳動泵督,按值控制滑動條的進度。
二庶喜、成功展示
三小腊、接入使用
1.接入
直接將CYCircularSlider.h和CYCircularSlider.m文件拖到項目中即可
2.使用
CGRect sliderFrame = CGRectMake(([UIScreen mainScreen].bounds.size.width-275)/2, ([UIScreen mainScreen].bounds.size.height-275)/2, 275,275);
_circularSlider =[[CYCircularSlider alloc]initWithFrame:sliderFrame];
[self.view addSubview:_circularSlider];
//設(shè)置代理
_circularSlider.delegate = self;
四救鲤、實現(xiàn)原理
整控件繼承UIControl,根據(jù)值的改變重新繪制layer和改變thumb的位置秩冈;根據(jù)手勢所在的位置本缠,重新layer和改變thumb的位置,并且改變值入问。
1.根據(jù)所給_angle繪制圓弧
在- (void)drawRect:(CGRect)rect;
方法中繪制圓弧
在ios中丹锹,圓弧的起始弧度為140,終點弧度為40(或者說為400)芬失,圓心為(self.frame.size.width/2楣黍,self.frame.size.height/2)
,弧長對應(yīng)的變量就是運動的點相對于起點旋轉(zhuǎn)過的角度棱烂,而這個角度就等于M_PI/180*(_angle)
租漂。
下面給出背景圓弧和進度圓弧的繪制方法
#pragma mark 畫圓
-(void)drawRect:(CGRect)rect{
[super drawRect:rect];
//畫固定的下層圓
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextAddArc(ctx, self.frame.size.width/2, self.frame.size.height/2, radius, M_PI/180*140, M_PI/180*40, 0);
[_unfilledColor setStroke];
CGContextSetLineWidth(ctx, _lineWidth);
CGContextSetLineCap(ctx, kCGLineCapButt);
CGContextDrawPath(ctx, kCGPathStroke);
CGContextAddArc(ctx, self.frame.size.width/2, self.frame.size.height/2, radius, M_PI/180*140, M_PI/180*(_angle), 0);
//畫可滑動的上層圓
[_filledColor setStroke];
CGContextSetLineWidth(ctx, _lineWidth);
CGContextSetLineCap(ctx, kCGLineCapButt);
CGContextDrawPath(ctx, kCGPathStroke);
[self drawHandle:ctx];
}
在值改變的時候重新繪制layer
#pragma mark 設(shè)置進度條位置
-(void)setAngel:(int)num{
_angle = num;
[self setNeedsDisplay];
}
2.繪制thumb以及確保在圓弧上運動
#pragma mark 畫thumb
-(void)drawHandle:(CGContextRef)ctx{
CGContextSaveGState(ctx);
CGPointhandleCenter = [self pointFromAngle: _angle];
[_handleColor set];
CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x-2.5, handleCenter.y-2.5, _lineWidth+5, _lineWidth+5));
CGContextRestoreGState(ctx);
}
3.拖動控制。
主要是在UIControl的以下三個方法上做文章:
//點擊開始
- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event;
//拖動過程中
- (BOOL)continueTrackingWithTouch:(UITouch
*)touch withEvent:(UIEvent *)event;
//拖動結(jié)束
- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event;
實現(xiàn)如下:
-(BOOL)
continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
[super continueTrackingWithTouch:touch withEvent:event];
CGPoint lastPoint = [touch locationInView:self];
//用于排除點在圓外面點與圓心半徑80以內(nèi)的點
if ((lastPoint.x>=0&&lastPoint.x<=275)&&(lastPoint.y>=0 && lastPoint.y<=275)) {
if ((lastPoint.x<=57.5||lastPoint.x>=217.5)||(lastPoint.y<=57.5 ||lastPoint.y>=217.5)) {
[self moveHandle:lastPoint];
}
}
[self sendActionsForControlEvents:UIControlEventValueChanged];
return YES;
}
-(void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{
[super endTrackingWithTouch:touch withEvent:event];
[self.delegate senderVlueWithNum:(int8_t)roundf(_currentValue)];
}
在拖動過程中處理數(shù)據(jù)颊糜、實現(xiàn)重繪layer改變_angle值哩治,在拖動結(jié)束中實現(xiàn)代理方法。
4.對于當值為0時衬鱼,滑塊不可以再逆時針滑動业筏,當值為最大值時,滑塊不可以再順時針滑動鸟赫。
只要判斷_angle>40 && _angle< 140
時驾孔,將_angle
拋出就可以了。
五惯疙、尾言
1翠勉、參考資料
iOS 圓環(huán)型滑塊(Circle Slider)
EFCircularSlider
2、下載傳送門
CYCircularSlider下載鏈接
或GitHub下載鏈接
3.再說幾句
因為實在是比較忙,而且沉不住心來寫的太仔細,項目里面也有很多地方寫的有問題和不夠好晃财,以后有時間再修改陵且,有問題也請大家留言,我會改正的。
另外總得來說,弧形滑動條是就是把圓形滑動條的起始位置和終點位置經(jīng)過修改,然后計算繪制弧長的參數(shù)等也要進行一些修改骑脱。