//
|
// HDLDiyImageSeekBar.m
|
// HDL_Widget_iOS
|
//
|
// Created by HDL on 2019/12/6.
|
// Copyright © 2019 JLChen. All rights reserved.
|
//
|
|
#import "HDLDiyImageSeekBar.h"
|
#import "HDLUtlisXM.h"
|
|
#define APP_DEFAULT_OFFLINE_COLOR HEXCOLORA(0xE9E9EC,0.8)
|
|
@interface HDLDiyImageSeekBar ()
|
|
|
|
/**
|
是否正在移动
|
*/
|
@property (nonatomic, assign) BOOL bTouchMove;
|
|
/**
|
进度单位符号
|
*/
|
@property (nonatomic, strong) NSString *mProgressBarUnitSring;
|
|
/**
|
最小值
|
*/
|
@property (nonatomic, assign) float mMinValue;
|
|
/**
|
最大值
|
*/
|
@property (nonatomic, assign) float mMaxValue;
|
|
|
/**
|
边距
|
*/
|
@property (nonatomic, assign) int DiyBarPadding;
|
|
/**
|
|
*/
|
//@property (nonatomic, strong) UIImageView *bgImageView;
|
|
|
|
///**
|
// 顶部padding
|
// */
|
//@property (nonatomic, assign) int mDiyBarPaddingTop;
|
|
|
/**
|
是否离线
|
*/
|
@property (nonatomic, assign) BOOL isOffline;
|
|
@end
|
|
|
@implementation HDLDiyImageSeekBar{
|
|
int _mMoveCount;
|
|
CGPoint _mCenterPoint; //圆心坐标
|
|
bool _bIsInDiyBarProgress;
|
|
CGFloat _mDiyBarHeight;
|
CGFloat _mDiyBarWidth;
|
// CGFloat _mDiyBarWidthHalf;
|
|
// CGFloat _mDiyBarStartX;
|
// CGFloat _mDiyBarEndX;
|
|
float _mPercent;
|
|
CGFloat _mDiyBarPadding;
|
CGFloat _mButtonWidth;
|
CGFloat _mDiyBarX;
|
CGFloat _mCornerRadius;
|
UIImage *_buttonImage;
|
|
|
int _mDiyBarPaddingTop;
|
int _mDiyBarPaddingBottom;
|
}
|
|
-(instancetype)initWithFrame:(CGRect)frame{
|
self = [super initWithFrame:frame];
|
if (self) {
|
_isClickable = YES;
|
_mMoveCount = 0;
|
|
_mProgress = 0;
|
_mPercent = 0;
|
_mMaxValue = 100.0f;
|
_mMinValue = 0.0f;
|
_mCornerRadius = 0;
|
|
_mProgressTextColor = [UIColor blackColor];
|
_mProgressTextSize = 15;
|
_mProgressBarUnitSring = @"%";
|
_isProgressTextShow = YES;
|
// mDiyBarPaddingTop = 45;
|
_DiyBarPadding = 15;
|
|
self.mArcBackBarColor = APP_DEFAULT_OFFLINE_COLOR;
|
self.mProgressBarColor = UIColor.yellowColor;
|
_mDiyBarHeight = 10;
|
_mButtonWidth = _mDiyBarHeight * 2;
|
[self refreshFrame];
|
|
self.backgroundColor = [UIColor clearColor];
|
// _bgImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
|
// [_bgImageView setImage:[UIImage imageNamed:@"ic_wd_DiyBar_roll_bg"]];
|
// [self addSubview:_bgImageView];
|
|
// _DiyBarImage = [UIImage imageNamed:@"ic_wd_DiyBar_roll_progress"];
|
_buttonImage = [UIImage imageNamed:@"ic_wd_curtain_h_open"];
|
|
// _bgImage = [UIImage imageNamed:@"ic_wd_DiyBar_roll_bg"];
|
|
}
|
|
return self;
|
}
|
|
|
|
/**
|
刷新布局,更新关键值
|
|
*/
|
-(void)refreshFrame{
|
_mCenterPoint = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
|
[self onDiyBarSizeChange];
|
}
|
|
/**
|
刷新布局,更新关键值
|
|
*/
|
-(void)onDiyBarSizeChange{
|
_mDiyBarPadding = _DiyBarPadding;
|
_mDiyBarWidth = self.frame.size.width - _mDiyBarPadding*2;
|
_mDiyBarPaddingTop = (self.frame.size.height - _mDiyBarHeight)/2;
|
_mDiyBarPaddingBottom = (self.frame.size.height + _mDiyBarHeight)/2;
|
|
}
|
|
|
#pragma mark drawRect 绘制图形
|
-(void)drawRect:(CGRect)rect{
|
[super drawRect:rect];
|
CGContextRef ctx = UIGraphicsGetCurrentContext();
|
//将当前图形状态推入堆栈
|
CGContextSaveGState(ctx);
|
// //*********绘制背景*********
|
// [self drawBackIamge];
|
//*********绘制动态的进度条*********
|
[self drawProgressBar:ctx];
|
|
//*********绘制按钮图片*********
|
[self drawImageButton:ctx];
|
//*********绘制显示进度值文字*********
|
[self drawProgressText:ctx];
|
//*********如果离线绘制离线背景遮挡层*********
|
[self drawOfflineView:ctx];
|
|
|
|
//把堆栈顶部的状态弹出
|
CGContextRestoreGState(ctx);
|
|
}
|
|
//
|
///**
|
// 绘制边框
|
//
|
// @param ctx 画布
|
// */
|
//-(void)drawBorderPath:(CGContextRef)ctx{
|
// CGRect drawRect = {5+_mBackLineWidth/2, 5+_mBackLineWidth/2, self.frame.size.width-10-_mBackLineWidth, self.frame.size.height-10-_mBackLineWidth};
|
//
|
// UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:drawRect cornerRadius:_mCornerRadius];
|
// path.lineWidth = _mBackLineWidth; //线宽
|
// path.lineCapStyle = kCGLineCapRound; //弯角样式
|
// path.lineJoinStyle = kCGLineJoinBevel; //交点的样式
|
// [_mDiyBarBorderColor set];
|
//
|
// CGContextSetLineWidth(ctx, _mBackLineWidth);
|
// CGContextAddPath(ctx, path.CGPath);
|
// CGContextDrawPath(ctx, kCGPathStroke);
|
// // [path stroke]; //边框线颜色
|
//}
|
|
/**
|
如果离线绘制离线背景遮挡层
|
|
@param ctx 画布
|
*/
|
-(void)drawOfflineView:(CGContextRef)ctx{
|
if(_isOffline){
|
CGRect drawRect2 = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
|
UIBezierPath *path3 = [UIBezierPath bezierPathWithRoundedRect:drawRect2 cornerRadius:5];
|
[APP_DEFAULT_OFFLINE_COLOR set];
|
CGContextAddPath(ctx, path3.CGPath);
|
CGContextDrawPath(ctx, kCGPathFill);
|
}
|
|
}
|
|
///**
|
// 绘制背景图
|
// */
|
//-(void)drawBackIamge{
|
// //绘制背景图
|
// CGRect rectBgImage = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
|
// [_bgImage drawInRect:rectBgImage];
|
//}
|
|
|
|
/**
|
绘制进度条
|
|
@param ctx 画布
|
*/
|
-(void)drawProgressBar:(CGContextRef)ctx{
|
|
|
_mDiyBarX = _mPercent * _mDiyBarWidth + _mDiyBarPadding;
|
//*******绘制进度条背景*********
|
CGRect rectB = CGRectMake(_mDiyBarPadding, _mDiyBarPaddingTop, _mDiyBarWidth, _mDiyBarHeight);
|
CGContextSaveGState(ctx);
|
UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:rectB cornerRadius:rectB.size.height/2];
|
CGContextSetFillColorWithColor(ctx, self.mArcBackBarColor.CGColor);
|
[roundedRect fill];
|
|
UIBezierPath *roundedClipPath = [UIBezierPath bezierPathWithRect:rectB];
|
[roundedClipPath appendPath:roundedRect];
|
[roundedRect addClip];
|
|
//*******绘制进度条*********
|
if(_mPercent <= 0) return;
|
|
CGRect drawRect = CGRectMake(_mDiyBarPadding, _mDiyBarPaddingTop, _mDiyBarX - _mDiyBarPadding, _mDiyBarHeight);
|
UIBezierPath *roundedRect2 = [UIBezierPath bezierPathWithRoundedRect:drawRect byRoundingCorners:UIRectCornerTopLeft | UIRectCornerBottomLeft cornerRadii: CGSizeMake(drawRect.size.height/2, drawRect.size.height/2)];
|
CGContextSetFillColorWithColor(ctx, self.mProgressBarColor.CGColor);
|
[roundedRect2 fill];
|
|
}
|
|
|
|
/**
|
绘制进度显示值文字
|
|
@param ctx 画布
|
*/
|
-(void)drawProgressText:(CGContextRef)ctx{
|
if(_isProgressTextShow){
|
|
CGPoint mP = CGPointMake(_mDiyBarX , _mDiyBarPaddingTop -15);
|
[self drawString:[NSString stringWithFormat:@"%d%@", _mProgress, _mProgressBarUnitSring] outsidePoint:mP];
|
}
|
}
|
|
|
/**
|
绘制进度显示值文字
|
|
@param ctx 画布
|
*/
|
-(void)drawImageButton:(CGContextRef)ctx {
|
CGContextRestoreGState(ctx);// 恢复到之前的context
|
CGContextSaveGState(ctx);
|
|
|
CGRect rectImage = CGRectMake(_mDiyBarX - _mButtonWidth/2, _mCenterPoint.y - _mButtonWidth/2 , _mButtonWidth, _mButtonWidth);
|
|
[_buttonImage drawInRect:rectImage];
|
}
|
|
|
|
|
|
|
/**
|
drawString 现在当前进度值
|
@param mText 显示文本
|
@param outsidePoint 坐标
|
*/
|
- (void) drawString:(NSString *)mText outsidePoint:(CGPoint)outsidePoint{
|
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
|
paragraph.alignment = NSTextAlignmentCenter;
|
NSDictionary *dic = @{NSFontAttributeName : [UIFont systemFontOfSize:_mProgressTextSize],
|
NSForegroundColorAttributeName : _mProgressTextColor,
|
NSParagraphStyleAttributeName : paragraph
|
};
|
|
// CGRect textRect = CGRectMake(outsidePoint.x, outsidePoint.y, 80, 20);
|
// [mText drawInRect:textRect withAttributes:dic];
|
|
//2019-08-15 修改文字绘制方法,最终实现文本居中效果
|
CGSize textSize = [mText sizeWithAttributes:dic];
|
CGPoint textPoint = CGPointMake(outsidePoint.x - textSize.width/2, outsidePoint.y - textSize.height/2);//根据中点坐标绘制
|
[mText drawAtPoint:textPoint withAttributes:dic];
|
|
}
|
|
|
|
|
|
#pragma mark Touch Event 点击事件
|
-(BOOL) beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
|
[super beginTrackingWithTouch:touch withEvent:event];
|
if(!_isClickable) return YES;//禁止点击
|
_bTouchMove = NO;
|
_mMoveCount = 0;
|
|
// CGPoint startPoint = [touch locationInView:self];
|
// _bIsInArcProgress = [self getStartPointIsInArcProgress:startPoint];//判断开始坐标是否在可点击区域
|
|
|
_bIsInDiyBarProgress = YES;//不限制点击区域
|
[self.mProgressChangedDelegate onStartTrackingTouch];
|
return YES;
|
}
|
|
-(void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{
|
[super endTrackingWithTouch:touch withEvent:event];
|
if(!_isClickable) return;//禁止点击
|
if(!_bTouchMove){//没移动,仅点击
|
CGPoint lastPoint = [touch locationInView:self];
|
[self getCurrentProgressWithLastPoint:lastPoint];
|
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
}
|
[self.mProgressChangedDelegate onStopTrackingTouch:_mProgress];
|
}
|
|
|
-(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
|
[super continueTrackingWithTouch:touch withEvent:event];
|
if(!_isClickable) return YES;//禁止点击
|
if(_mMoveCount < 2){
|
_mMoveCount++;
|
}else{
|
_bTouchMove = YES; //开始移动
|
}
|
|
if(_bIsInDiyBarProgress){//如果刚开始点击的坐标在可点击区域
|
CGPoint lastPoint = [touch locationInView:self];
|
[self getCurrentProgressWithLastPoint:lastPoint];
|
}
|
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
return YES;
|
}
|
|
|
/**
|
根据坐标计算出当前进度百分比和对应的进度值
|
|
@param point 当前坐标
|
*/
|
-(void)getCurrentProgressWithLastPoint:(CGPoint)point {
|
|
_mPercent = (point.x - _mDiyBarPadding ) / _mDiyBarWidth;
|
|
// NSLog(@"point.y:%f _mDiyBarHeight:%f",point.x, _mDiyBarWidthHalf);
|
// NSLog(@"_mPercent:%f",_mPercent);
|
//
|
|
//
|
if(_mPercent > 1){
|
_mPercent = 1;
|
}else if(_mPercent < 0){
|
_mPercent = 0;
|
}
|
|
_mProgress = (_mPercent) * (_mMaxValue - _mMinValue) + _mMinValue;
|
|
if(_bTouchMove){
|
[self.mProgressChangedDelegate onProgressChanged:_mProgress];
|
}
|
|
[self setNeedsDisplay];
|
}
|
|
|
/**
|
根据进度值,计算当前 _mProgressAngle值
|
|
@param mProgress 进度值
|
*/
|
-(void)setSeekBarProgressToValue:(int)mProgress{
|
if(mProgress < _mMinValue){
|
mProgress = _mMinValue;
|
}
|
if(mProgress > _mMaxValue){
|
mProgress = _mMaxValue;
|
}
|
_mProgress = mProgress;
|
_mPercent = (_mProgress - _mMinValue) / (_mMaxValue - _mMinValue);
|
// [self.mProgressChangedDelegate onProgressChanged:_mProgress];
|
}
|
|
#pragma mark 设置进度条位置
|
/**
|
设置进度值
|
|
@param mProgress 进度值
|
*/
|
-(void)setProgress:(int)mProgress{
|
[self setSeekBarProgressToValue:mProgress];
|
[self setNeedsDisplay];
|
}
|
|
|
/**
|
设置进度显示值单位
|
|
@param mString 单位字符
|
*/
|
-(void)setProgressBarUnitSring:(NSString *)mString{
|
_mProgressBarUnitSring = mString;
|
}
|
|
|
/**
|
设置最大值最小值
|
|
@param mMinValue 最小值
|
@param mMaxValue 最大值
|
*/
|
-(void)setMinAndMaxValue:(float)mMinValue mMaxValue:(float)mMaxValue{
|
if(mMinValue < mMaxValue){
|
_mMinValue = mMinValue;
|
_mMaxValue = mMaxValue;
|
}else{
|
_mMinValue = mMaxValue;
|
_mMaxValue = mMinValue;
|
}
|
_mProgress = _mMinValue;
|
_mPercent = 0.0f;
|
}
|
|
|
/**
|
重置布局
|
|
@param mCGRect 布局
|
|
*/
|
-(void)initWithFrameSeekBar:(CGRect) mCGRect{
|
self.frame = mCGRect;
|
[self refreshFrame];
|
}
|
|
|
/**
|
设置边距
|
*/
|
-(void)setSeekBarPadding:(int)Padding{
|
_DiyBarPadding = Padding;
|
[self onDiyBarSizeChange];
|
}
|
|
/**
|
设置进度条高
|
*/
|
-(void)setProgressBarHeight:(int)mHeight{
|
_mDiyBarHeight = mHeight;
|
[self onDiyBarSizeChange];
|
|
}
|
|
/**
|
设置按钮高度
|
*/
|
-(void)setBitmapButtonHeight:(int)mHeight{
|
_mButtonWidth = mHeight;
|
|
}
|
|
/**
|
设置拖动按钮图片
|
*/
|
-(void)setBgBitmapButton:(UIImage*) mImage{
|
_buttonImage = mImage;
|
}
|
|
/**
|
设置是否离线
|
*/
|
-(void)setOffline:(BOOL)isOffline{
|
_isOffline = isOffline;
|
_isClickable = !_isOffline;
|
[self setNeedsDisplay];
|
}
|
|
@end
|