美文网首页iOS
MBBarProgressView-从drawRect学习自定义

MBBarProgressView-从drawRect学习自定义

作者: 码农二哥 | 来源:发表于2016-11-02 11:05 被阅读37次
    MBBarProgressView-Demo.png
    /**
     * A flat bar progress view. 
     */
    @interface MBBarProgressView : UIView
    
    /**
     * Progress (0.0 to 1.0)
     */
    @property (nonatomic, assign) float progress;
    
    /**
     * Bar border line color.
     * Defaults to white [UIColor whiteColor].
     */
    @property (nonatomic, strong) UIColor *lineColor;
    
    /**
     * Bar background color.
     * Defaults to clear [UIColor clearColor];
     */
    @property (nonatomic, strong) UIColor *progressRemainingColor;
    
    /**
     * Bar progress color.
     * Defaults to white [UIColor whiteColor].
     */
    @property (nonatomic, strong) UIColor *progressColor;
    
    @end
    
    @implementation MBBarProgressView
    
    #pragma mark - Lifecycle
    
    - (id)init {
        return [self initWithFrame:CGRectMake(.0f, .0f, 120.0f, 20.0f)];
    }
    
    - (id)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if (self) {
            _progress = 0.f;
            _lineColor = [UIColor whiteColor];
            _progressColor = [UIColor whiteColor];
            _progressRemainingColor = [UIColor clearColor];
            self.backgroundColor = [UIColor clearColor];
            self.opaque = NO;
        }
        return self;
    }
    
    #pragma mark - Layout
    
    - (CGSize)intrinsicContentSize {
        BOOL isPreiOS7 = kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0;
        return CGSizeMake(120.f, isPreiOS7 ? 20.f : 10.f);
    }
    
    #pragma mark - Properties
    
    - (void)setProgress:(float)progress {
        if (progress != _progress) {
            _progress = progress;
            [self setNeedsDisplay];
        }
    }
    
    - (void)setProgressColor:(UIColor *)progressColor {
        NSAssert(progressColor, @"The color should not be nil.");
        if (progressColor != _progressColor && ![progressColor isEqual:_progressColor]) {
            _progressColor = progressColor;
            [self setNeedsDisplay];
        }
    }
    
    - (void)setProgressRemainingColor:(UIColor *)progressRemainingColor {
        NSAssert(progressRemainingColor, @"The color should not be nil.");
        if (progressRemainingColor != _progressRemainingColor && ![progressRemainingColor isEqual:_progressRemainingColor]) {
            _progressRemainingColor = progressRemainingColor;
            [self setNeedsDisplay];
        }
    }
    
    #pragma mark - Drawing
    
    - (void)drawRect:(CGRect)rect {
        CGContextRef context = UIGraphicsGetCurrentContext();
        
        CGContextSetLineWidth(context, 2);
        CGContextSetStrokeColorWithColor(context,[_lineColor CGColor]);
        CGContextSetFillColorWithColor(context, [_progressRemainingColor CGColor]);
        
        // Draw background
        CGFloat radius = (rect.size.height / 2) - 2;
        CGContextMoveToPoint(context, 2, rect.size.height/2);
        CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius);
        CGContextAddLineToPoint(context, rect.size.width - radius - 2, 2);
        CGContextAddArcToPoint(context, rect.size.width - 2, 2, rect.size.width - 2, rect.size.height / 2, radius);
        CGContextAddArcToPoint(context, rect.size.width - 2, rect.size.height - 2, rect.size.width - radius - 2, rect.size.height - 2, radius);
        CGContextAddLineToPoint(context, radius + 2, rect.size.height - 2);
        CGContextAddArcToPoint(context, 2, rect.size.height - 2, 2, rect.size.height/2, radius);
        CGContextFillPath(context);
        
        // Draw border(和上面一段只有最后一句话不一样)
        CGContextMoveToPoint(context, 2, rect.size.height/2);
        CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius);
        CGContextAddLineToPoint(context, rect.size.width - radius - 2, 2);
        CGContextAddArcToPoint(context, rect.size.width - 2, 2, rect.size.width - 2, rect.size.height / 2, radius);
        CGContextAddArcToPoint(context, rect.size.width - 2, rect.size.height - 2, rect.size.width - radius - 2, rect.size.height - 2, radius);
        CGContextAddLineToPoint(context, radius + 2, rect.size.height - 2);
        CGContextAddArcToPoint(context, 2, rect.size.height - 2, 2, rect.size.height/2, radius);
        CGContextStrokePath(context);
    
        CGContextSetFillColorWithColor(context, [_progressColor CGColor]);
        radius = radius - 2;
        CGFloat amount = self.progress * rect.size.width;
    
        // Progress in the middle area(left padding=2,line border=2 2+2=4)
        if (amount >= radius + 4 && amount <= (rect.size.width - radius - 4)) {
            CGContextMoveToPoint(context, 4, rect.size.height/2);
            CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);
            CGContextAddLineToPoint(context, amount, 4);
            CGContextAddLineToPoint(context, amount, radius + 4);
            
            CGContextMoveToPoint(context, 4, rect.size.height/2);
            CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius);
            CGContextAddLineToPoint(context, amount, rect.size.height - 4);
            CGContextAddLineToPoint(context, amount, radius + 4);
            
            CGContextFillPath(context);
        }
        
        // Progress in the right arc
        else if (amount > radius + 4) {
            CGFloat x = amount - (rect.size.width - radius - 4);
    
            CGContextMoveToPoint(context, 4, rect.size.height/2);
            CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);
            CGContextAddLineToPoint(context, rect.size.width - radius - 4, 4);
            CGFloat angle = -acos(x/radius);
            if (isnan(angle)) angle = 0;
            CGContextAddArc(context, rect.size.width - radius - 4, rect.size.height/2, radius, M_PI, angle, 0);
            CGContextAddLineToPoint(context, amount, rect.size.height/2);
    
            CGContextMoveToPoint(context, 4, rect.size.height/2);
            CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius);
            CGContextAddLineToPoint(context, rect.size.width - radius - 4, rect.size.height - 4);
            angle = acos(x/radius);
            if (isnan(angle)) angle = 0;
            CGContextAddArc(context, rect.size.width - radius - 4, rect.size.height/2, radius, -M_PI, angle, 1);
            CGContextAddLineToPoint(context, amount, rect.size.height/2);
            
            CGContextFillPath(context);
        }
        
        // Progress is in the left arc
        else if (amount < radius + 4 && amount > 0) {
            CGContextMoveToPoint(context, 4, rect.size.height/2);
            CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);
            CGContextAddLineToPoint(context, radius + 4, rect.size.height/2);
    
            CGContextMoveToPoint(context, 4, rect.size.height/2);
            CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius);
            CGContextAddLineToPoint(context, radius + 4, rect.size.height/2);
            
            CGContextFillPath(context);
        }
    }
    
    @end
    
    - (void)myTest
    {
    static MBBarProgressView *bpv;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    bpv = [[MBBarProgressView alloc] initWithFrame:CGRectMake(0, 300, 120, 20)];
    [bpv setProgress:0.5];
    [bpv setProgressColor:[UIColor redColor]];
    [bpv setProgressRemainingColor:[UIColor blueColor]];
    [bpv setLineColor:[UIColor purpleColor]];
    [self.navigationController.view addSubview:bpv];
    });
    [bpv setProgress:bpv.progress + 0.1];
    }
    

    References

    相关文章

      网友评论

        本文标题:MBBarProgressView-从drawRect学习自定义

        本文链接:https://www.haomeiwen.com/subject/ruevuttx.html