Question

Using Quartz 2D like Foursquare rating:

Please see link; look for the green circle, for example.

Thanks in advance.

 (void)drawRect:(CGRect)rect {

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 4.0);
    CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
    UIColor *theFillColor = [UIColor greenColor];
    CGContextSetFillColorWithColor(context, theFillColor.CGColor);
    CGRect rectangle = CGRectMake(50.0,150.0,rect.size.width-10.0,rect.size.height-10.0);
    CGContextBeginPath(context);
    CGContextAddEllipseInRect(context, rectangle);
    CGContextDrawPath(context, kCGPathFillStroke); // Or kCGPathFill
    CGRect smallRect = CGRectInset(rectangle, 40, 40);
    CGContextBeginPath(context);
    CGContextAddEllipseInRect(context, smallRect);
    CGContextDrawPath(context, kCGPathFillStroke); // Or kCGPathFill
    UIGraphicsEndImageContext();
}

drow rect is never called i am loading UI from xib ?

Was it helpful?

Solution

Here's a sample class I whipped up. It's not a true "animation", but gives the correct appearance of one:

#import <UIKit/UIKit.h>
@interface MSSNumberWithCircleView : UIView {

}
@property (assign, nonatomic) NSInteger  number;
@property (strong, nonatomic) UIColor   *circleColor;
@property (strong, nonatomic) UIColor   *numberColor;
@property (strong, nonatomic) UIFont    *numberFont;
- (id)initWithNumber:(NSInteger)number numberFont:(UIFont *)numberFont numberColor:(UIColor *)numberColor circleColor:(UIColor *)circleColor;
@end

// Header import
#import "MSSNumberWithCircleView.h"
// Other imports

@interface MSSNumberWithCircleView () {

}
@property (assign, nonatomic) CGFloat angle;
@property (assign, nonatomic) CGFloat animationDuration;
@property (assign, nonatomic) CGFloat animationFrames;
+ (NSInteger)defaultNumber;
+ (UIColor *)defaultCircleColor;
+ (UIColor *)defaultNumberColor;
+ (UIFont *)defaultNumberFont;
@end
@implementation MSSNumberWithCircleView
#pragma mark - Class Methods (Default Property Values)
+ (NSInteger)defaultNumber {
    return 1;
}
+ (UIColor *)defaultCircleColor {
    static UIColor *defaultColor = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        defaultColor = [UIColor colorWithRed:136.0f/255.0f 
                                       green:190.0f/255.0f 
                                        blue:050.0f/255.0f 
                                       alpha:1.0f];
    });
    return defaultColor;
}
+ (UIColor *)defaultNumberColor {
    static UIColor *defaultColor = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        defaultColor = [UIColor whiteColor];
    });
    return defaultColor;
}
+ (UIFont *)defaultNumberFont {
    static UIFont *defaultFont = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        defaultFont = [UIFont fontWithName:@"HelveticaNeue-Light" size:240.0f];
    });
    return defaultFont;
}
#pragma mark - Initialization Methods
- (id)init {
    self = [super init];
    if (self != nil) {
        [self defaultSetup];
    }
    return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self != nil) {
        [self defaultSetup];
    }
    return self;
}
- (id)initWithNumber:(NSInteger)number numberFont:(UIFont *)numberFont numberColor:(UIColor *)numberColor circleColor:(UIColor *)circleColor {
    self = [super init];
    if (self != nil) {
        self.circleColor        = circleColor;
        self.numberColor        = numberColor;
        self.numberFont         = numberFont;
        self.number             = number;
    }
    return self;
}
- (void)defaultSetup {
    self.angle              = 0;
    self.animationDuration  = 0.4f;
    self.animationFrames    = 30;
    self.circleColor        = [MSSNumberWithCircleView defaultCircleColor];
    self.numberColor        = [MSSNumberWithCircleView defaultNumberColor];
    self.numberFont         = [MSSNumberWithCircleView defaultNumberFont];
    self.number             = [MSSNumberWithCircleView defaultNumber];
}
- (void)drawRect:(CGRect)rect {

    self.angle = self.angle + (2 * M_PI / self.animationFrames);

    CGContextRef context    = UIGraphicsGetCurrentContext();

    CGFloat circleSide      = MIN(rect.size.height, rect.size.width);
    CGFloat xOffset         = (rect.size.width  - circleSide) / 2.0f;
    CGFloat yOffset         = (rect.size.height - circleSide) / 2.0f;

    CGRect circleRect       = CGRectMake(xOffset, yOffset, circleSide, circleSide);
    CGPoint circleCenter    = CGPointMake(CGRectGetMidX(circleRect), CGRectGetMidY(circleRect));

    CGRect textRect         = CGRectInset(circleRect, circleSide * 0.1f, circleSide * 0.1f);
    CGFloat textSide        = textRect.size.width;

    [self.circleColor setFill];

    CGContextMoveToPoint(context, circleCenter.x, circleCenter.y);
    CGContextAddArc(context, circleCenter.x, circleCenter.y, circleSide / 2.0f, 0, self.angle, NO);
    CGContextFillPath(context);

    NSString *numberString  = [NSString stringWithFormat:@"%d", (int)self.number];
    NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    style.alignment = NSTextAlignmentCenter;
    NSDictionary *drawDict  = @{NSFontAttributeName: self.numberFont, NSParagraphStyleAttributeName: style};

    CGSize size             = [numberString boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT)
                                                     options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin
                                                  attributes:drawDict
                                                         context:nil].size;
    CGFloat fontSize        = self.numberFont.pointSize;
    CGFloat measuredSide    = MAX(size.width, size.height);

    fontSize                = fontSize * (textSide / measuredSide);

    self.numberFont         = [self.numberFont fontWithSize:fontSize];
    drawDict                = @{NSFontAttributeName: self.numberFont, NSParagraphStyleAttributeName: style, NSForegroundColorAttributeName: self.numberColor};

    [numberString drawWithRect:textRect
                       options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin
                    attributes:drawDict
                       context:nil];

    if (self.angle <= (2 * M_PI)) {
        [self performSelector:@selector(setNeedsDisplay) withObject:nil afterDelay:(self.animationDuration / self.animationFrames)];

    } else {
        self.angle = 0;

    }
}
@end

Basically, change your properties to adjust the duration of the animation. I made those values private, but you could put them in your header if you want them to be publicly accessible. Also, I pulled the defaultNumberColor from the page you posted.

Also, this is designed to make a square (for the bounds of the circle) from the shorter side of the view you have setup in Interface Builder. It will then center the square in the view. This class is designed so that a call to -setNeedsDisplay will trigger the entire animation, which will "reset" the class for the next animation when it's done.

OTHER TIPS

Are you sure that you've placed drawRect: method in UIView subclass? You can call it manually by call [self setNeedsDisplay], but its very strange that in won't triggered automatically. Can you show how you instantiate your view via XIB?

If your UIView subclass's drawRect is never called, it seems most likely that you have forgotten to set this view, in the nib editor, to be an instance of your UIView subclass.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top