https://github.com/YouXianMing

[翻译] GSProgressView

GSProgressView

 

本人极不推荐使用drawRect的方式来绘制下载进度条,无论机器的性能怎么高,使用drawRect用于绘制图形都是低效的。

 

A cute little circular progress view for iOS

一款轻巧的显示圆形进度的的view,用于iOS开发

 

Installation - 安装

Drag GSProgressView.h and GSProgressView.m into your project.

将GSProgressView.h与GSProgressView.m拖到你的工程当中。

 

Serving suggestion - 建议的使用方式

GSProgressView *pv = [[GSProgressView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
pv.color = [UIColor redColor];
pv.progress = 0.6;
[myView addSubview:pv];

GSProgressView.h +
GSProgressView.m
//
//  GSProgressView.h
//
//  Created by Simon Whitaker on 14/11/2012.
//  Copyright (c) 2012 Goo Software Ltd. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface GSProgressView : UIView

@property (nonatomic) CGFloat progress;
@property (strong, nonatomic) UIColor *color UI_APPEARANCE_SELECTOR;
@property (strong, nonatomic) UIColor *tickColor UI_APPEARANCE_SELECTOR;

@end
//
//  GSProgressView.m
//
//  Created by Simon Whitaker on 14/11/2012.
//  Copyright (c) 2012 Goo Software Ltd. All rights reserved.
//

#import "GSProgressView.h"
#import <QuartzCore/QuartzCore.h>

@implementation GSProgressView

- (void)commonInit {
    self.backgroundColor = [UIColor clearColor];
}

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (void)setProgress:(CGFloat)progress {
    if (progress > 1.0) progress = 1.0;
    
    if (progress != _progress) {
        _progress = progress;
        [self setNeedsDisplay];
    }
}

- (void)drawRect:(CGRect)rect {
    if ([self color] == nil)
        [self setColor:[UIColor blackColor]];
    
    CGPoint center = CGPointMake(rect.size.width/2, rect.size.height/2);
    CGFloat radius = MIN(rect.size.width, rect.size.height)/2;
    
    // Start a path
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    // Move to centre and draw an arc.
    
    [path moveToPoint:center];
    [path addArcWithCenter:center
                    radius:radius
                startAngle:0 - M_PI_2 // zero degrees is east, not north, so subtract pi/2
                  endAngle:2 * M_PI * [self progress] - M_PI_2 // ditto
                 clockwise:YES];
    [path closePath];
    
    // If progress is 1.0, show a tick mark in the centre of the circle
    if ([self progress] == 1.0) {
        /* 
         First draw a tick that looks like this:
         
           A---F
           |   |
           |   E-------D
           |           |
           B-----------C
         
         (Remember: (0,0) is top left)
         */
        UIBezierPath *tickPath = [UIBezierPath bezierPath];
        CGFloat tickWidth = radius/3;
        [tickPath moveToPoint:CGPointMake(0, 0)];                            // A
        [tickPath addLineToPoint:CGPointMake(0, tickWidth * 2)];             // B
        [tickPath addLineToPoint:CGPointMake(tickWidth * 3, tickWidth * 2)]; // C
        [tickPath addLineToPoint:CGPointMake(tickWidth * 3, tickWidth)];     // D
        [tickPath addLineToPoint:CGPointMake(tickWidth, tickWidth)];         // E
        [tickPath addLineToPoint:CGPointMake(tickWidth, 0)];                 // F
        [tickPath closePath];
        
        // Now rotate it through -45 degrees...
        [tickPath applyTransform:CGAffineTransformMakeRotation(-M_PI_4)];
        
        // ...and move it into the right place.
        [tickPath applyTransform:CGAffineTransformMakeTranslation(radius * 0.43, radius)];
        
        // Account for non-square views
        CGFloat xOffset = rect.size.width/2 - radius;
        CGFloat yOffset = rect.size.height/2 - radius;
        [tickPath applyTransform:CGAffineTransformMakeTranslation(xOffset, yOffset)];

        // Add fill color if it's set
        if (self.tickColor) {
            [[self tickColor] setFill];
            [tickPath fill];
        }

        // Add the tick path to the existing circle path
        [path appendPath:tickPath];
    };
    path.usesEvenOddFillRule = YES;
    
    [[self color] setFill];
    [path fill];
}

#pragma mark - Accessibility

- (BOOL)isAccessibilityElement {
    return YES;
}

- (NSString *)accessibilityLabel {
    return NSLocalizedString(@"Progress", @"Accessibility label for GSProgressView");
}

- (NSString *)accessibilityValue {
    // Report progress as a percentage, same as UISlider, UIProgressView
    return [NSString stringWithFormat:@"%d%%", (int)round([self progress] * 100.0)];
}

- (UIAccessibilityTraits)accessibilityTraits {
    return UIAccessibilityTraitUpdatesFrequently;
}

@end

 

 

 

 

 

 

posted @ 2014-06-15 07:09  YouXianMing  阅读(473)  评论(0编辑  收藏  举报