diff --git a/MONActivityIndicatorViewDemo/MONActivityIndicatorViewDemo/Source/Controllers/MONViewController.m b/MONActivityIndicatorViewDemo/MONActivityIndicatorViewDemo/Source/Controllers/MONViewController.m index 2707b05..4e422a0 100644 --- a/MONActivityIndicatorViewDemo/MONActivityIndicatorViewDemo/Source/Controllers/MONViewController.m +++ b/MONActivityIndicatorViewDemo/MONActivityIndicatorViewDemo/Source/Controllers/MONViewController.m @@ -20,47 +20,28 @@ @implementation MONViewController - (void)viewDidLoad { [super viewDidLoad]; - + MONActivityIndicatorView *indicatorView = [[MONActivityIndicatorView alloc] init]; - indicatorView.delegate = self; - indicatorView.numberOfCircles = 3; - indicatorView.radius = 20; - indicatorView.internalSpacing = 3; + // indicatorView.delegate = self; [indicatorView startAnimating]; - + indicatorView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:indicatorView]; - [self placeAtTheCenterWithView:indicatorView]; + NSDictionary *views = @{ @"indicatorView" : indicatorView, + @"superview" : self.view }; + [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[superview]-(<=1)-[indicatorView]" options:NSLayoutFormatAlignAllCenterX metrics:nil views:views]]; + [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[superview]-(<=1)-[indicatorView]" options:NSLayoutFormatAlignAllCenterY metrics:nil views:views]]; + [NSTimer scheduledTimerWithTimeInterval:7 target:indicatorView selector:@selector(stopAnimating) userInfo:nil repeats:NO]; [NSTimer scheduledTimerWithTimeInterval:9 target:indicatorView selector:@selector(startAnimating) userInfo:nil repeats:NO]; } -#pragma mark - -#pragma mark - Centering Indicator View -- (void)placeAtTheCenterWithView:(UIView *)view { - [self.view addConstraint:[NSLayoutConstraint constraintWithItem:view - attribute:NSLayoutAttributeCenterX - relatedBy:NSLayoutRelationEqual - toItem:self.view - attribute:NSLayoutAttributeCenterX - multiplier:1.0f - constant:0.0f]]; - - [self.view addConstraint:[NSLayoutConstraint constraintWithItem:view - attribute:NSLayoutAttributeCenterY - relatedBy:NSLayoutRelationEqual - toItem:self.view - attribute:NSLayoutAttributeCenterY - multiplier:1.0f - constant:0.0f]]; -} #pragma mark - #pragma mark - MONActivityIndicatorViewDelegate Methods -- (UIColor *)activityIndicatorView:(MONActivityIndicatorView *)activityIndicatorView - circleBackgroundColorAtIndex:(NSUInteger)index { +- (UIColor *)activityIndicatorView:(MONActivityIndicatorView *)activityIndicatorView dotColorAtIndex:(NSUInteger)index { CGFloat red = (arc4random() % 256)/255.0; CGFloat green = (arc4random() % 256)/255.0; CGFloat blue = (arc4random() % 256)/255.0; diff --git a/MONActivityIndicatorViewDemo/MONActivityIndicatorViewDemo/Source/Views/MONActivityIndicatorView/MONActivityIndicatorView.h b/MONActivityIndicatorViewDemo/MONActivityIndicatorViewDemo/Source/Views/MONActivityIndicatorView/MONActivityIndicatorView.h index 74e3145..bd83710 100644 --- a/MONActivityIndicatorViewDemo/MONActivityIndicatorViewDemo/Source/Views/MONActivityIndicatorView/MONActivityIndicatorView.h +++ b/MONActivityIndicatorViewDemo/MONActivityIndicatorViewDemo/Source/Views/MONActivityIndicatorView/MONActivityIndicatorView.h @@ -8,25 +8,25 @@ @protocol MONActivityIndicatorViewDelegate; -@interface MONActivityIndicatorView : UIView +@interface MONActivityIndicatorView : UIView /** The number of circle indicators. */ -@property (readwrite, nonatomic) NSUInteger numberOfCircles; +@property (nonatomic) IBInspectable NSUInteger numberOfCircles; //UI_APPEARANCE_SELECTOR /** The spacing between circles. */ -@property (readwrite, nonatomic) CGFloat internalSpacing; +@property (nonatomic) IBInspectable CGFloat internalSpacing; //UI_APPEARANCE_SELECTOR /** The radius of each circle. */ -@property (readwrite, nonatomic) CGFloat radius; +@property (nonatomic) IBInspectable CGFloat radius; //UI_APPEARANCE_SELECTOR /** The base animation delay of each circle. */ -@property (readwrite, nonatomic) CGFloat delay; +@property (nonatomic) IBInspectable CGFloat delay; //UI_APPEARANCE_SELECTOR /** The base animation duration of each circle*/ -@property (readwrite, nonatomic) CGFloat duration; +@property (nonatomic) IBInspectable CGFloat duration; //UI_APPEARANCE_SELECTOR /** The assigned delegate */ -@property (weak, nonatomic) id delegate; +@property (nonatomic, weak) id delegate; /** @@ -51,7 +51,6 @@ @param index The index of a particular circle. @return The background color of a particular circle. */ -- (UIColor *)activityIndicatorView:(MONActivityIndicatorView *)activityIndicatorView - circleBackgroundColorAtIndex:(NSUInteger)index; +- (UIColor *)activityIndicatorView:(MONActivityIndicatorView *)activityIndicatorView dotColorAtIndex:(NSUInteger)index; @end diff --git a/MONActivityIndicatorViewDemo/MONActivityIndicatorViewDemo/Source/Views/MONActivityIndicatorView/MONActivityIndicatorView.m b/MONActivityIndicatorViewDemo/MONActivityIndicatorViewDemo/Source/Views/MONActivityIndicatorView/MONActivityIndicatorView.m index df32a24..96a023a 100644 --- a/MONActivityIndicatorViewDemo/MONActivityIndicatorViewDemo/Source/Views/MONActivityIndicatorView/MONActivityIndicatorView.m +++ b/MONActivityIndicatorViewDemo/MONActivityIndicatorViewDemo/Source/Views/MONActivityIndicatorView/MONActivityIndicatorView.m @@ -7,78 +7,33 @@ #import #import "MONActivityIndicatorView.h" -@interface MONActivityIndicatorView () -/** The default color of each circle. */ -@property (strong, nonatomic) UIColor *defaultColor; -/** An indicator whether the activity indicator view is animating. */ -@property (readwrite, nonatomic) BOOL isAnimating; +@interface MONActivityIndicatorView () -/** - Sets up default values - */ -- (void)setupDefaults; -/** - Adds circles. - */ -- (void)addCircles; -/** - Removes circles. - */ -- (void)removeCircles; +/** An indicator whether the activity indicator view is animating. */ +@property (nonatomic) BOOL isAnimating; -/** - Creates the circle view. - @param radius The radius of the circle. - @param color The background color of the circle. - @param positionX The x-position of the circle in the contentView. - @return The circle view. - */ -- (UIView *)createCircleWithRadius:(CGFloat)radius color:(UIColor *)color positionX:(CGFloat)x; -/** - Creates the animation of the circle. - @param duration The duration of the animation. - @param delay The delay of the animation - @return The animation of the circle. - */ -- (CABasicAnimation *)createAnimationWithDuration:(CGFloat)duration delay:(CGFloat)delay; @end + + @implementation MONActivityIndicatorView -#pragma mark - -#pragma mark - Initializations -- (id)init { - self = [super initWithFrame:CGRectZero]; - if (self) { - [self setupDefaults]; - } - return self; -} -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - [self setupDefaults]; - } - return self; -} +@synthesize numberOfCircles = _numberOfCircles; +@synthesize internalSpacing = _internalSpacing; +@synthesize radius = _radius; +@synthesize delay = _delay; +@synthesize duration = _duration; + -- (id)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if (self) { - [self setupDefaults]; - } - return self; -} -#pragma mark - #pragma mark - Intrinsic Content Size - (CGSize)intrinsicContentSize { @@ -87,22 +42,33 @@ - (CGSize)intrinsicContentSize { return CGSizeMake(width, height); } -#pragma mark - + + #pragma mark - Private Methods -- (void)setupDefaults { - self.translatesAutoresizingMaskIntoConstraints = NO; - self.numberOfCircles = 5; - self.internalSpacing = 5; - self.radius = 10; - self.delay = 0.2; - self.duration = 0.8; - self.defaultColor = [UIColor lightGrayColor]; + + +- (void)refresh +{ + if (self.isAnimating) + { + [self removeCircles]; + [self addCircles]; + } + [self invalidateIntrinsicContentSize]; } -- (UIView *)createCircleWithRadius:(CGFloat)radius - color:(UIColor *)color - positionX:(CGFloat)x { + + +/** + Creates the circle view. + @param radius The radius of the circle. + @param color The background color of the circle. + @param positionX The x-position of the circle in the contentView. + @return The circle view. + */ +- (UIView *)createCircleWithRadius:(CGFloat)radius color:(UIColor *)color positionX:(CGFloat)x +{ UIView *circle = [[UIView alloc] initWithFrame:CGRectMake(x, 0, radius * 2, radius * 2)]; circle.backgroundColor = color; circle.layer.cornerRadius = radius; @@ -110,6 +76,12 @@ - (UIView *)createCircleWithRadius:(CGFloat)radius return circle; } +/** + Creates the animation of the circle. + @param duration The duration of the animation. + @param delay The delay of the animation + @return The animation of the circle. + */ - (CABasicAnimation *)createAnimationWithDuration:(CGFloat)duration delay:(CGFloat)delay { CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; anim.delegate = self; @@ -126,13 +98,11 @@ - (CABasicAnimation *)createAnimationWithDuration:(CGFloat)duration delay:(CGFlo - (void)addCircles { for (NSUInteger i = 0; i < self.numberOfCircles; i++) { - UIColor *color = nil; - if (self.delegate && [self.delegate respondsToSelector:@selector(activityIndicatorView:circleBackgroundColorAtIndex:)]) { - color = [self.delegate activityIndicatorView:self circleBackgroundColorAtIndex:i]; + UIColor *color = self.tintColor; + if (self.delegate && [self.delegate respondsToSelector:@selector(activityIndicatorView:dotColorAtIndex:)]) { + color = [self.delegate activityIndicatorView:self dotColorAtIndex:i]; } - UIView *circle = [self createCircleWithRadius:self.radius - color:(color == nil) ? self.defaultColor : color - positionX:(i * ((2 * self.radius) + self.internalSpacing))]; + UIView *circle = [self createCircleWithRadius:self.radius color:color positionX:(i * ((2 * self.radius) + self.internalSpacing))]; [circle setTransform:CGAffineTransformMakeScale(0, 0)]; [circle.layer addAnimation:[self createAnimationWithDuration:self.duration delay:(i * self.delay)] forKey:@"scale"]; [self addSubview:circle]; @@ -145,7 +115,8 @@ - (void)removeCircles { }]; } -#pragma mark - + + #pragma mark - Public Methods - (void)startAnimating { @@ -164,22 +135,100 @@ - (void)stopAnimating { } } -#pragma mark - -#pragma mark - Custom Setters and Getters + + +#pragma mark - *** Custom Setters and Getters *** + +#pragma mark - Number of Circles + +- (NSUInteger)numberOfCircles +{ + if (!_numberOfCircles) return 5; + return _numberOfCircles; +} + + - (void)setNumberOfCircles:(NSUInteger)numberOfCircles { _numberOfCircles = numberOfCircles; - [self invalidateIntrinsicContentSize]; + [self refresh]; +} + + + +#pragma mark - Radius + +- (CGFloat)radius +{ + if (!_radius) return 10.f; + return _radius; } - (void)setRadius:(CGFloat)radius { _radius = radius; - [self invalidateIntrinsicContentSize]; + [self refresh]; +} + + + +#pragma mark - Delay + +- (CGFloat)delay +{ + if (!_delay) return 0.2f; + return _delay; +} + + + +- (void)setDelay:(CGFloat)delay +{ + _delay = delay; + [self refresh]; +} + + + +#pragma mark - Duration + +- (CGFloat)duration +{ + if (!_duration) return 0.8f; + return _duration; +} + + + +- (void)setDuration:(CGFloat)duration +{ + _duration = duration; + [self refresh]; +} + + +#pragma mark - Internal Spacing + +- (CGFloat)internalSpacing +{ + if (!_internalSpacing) return 5; + return _internalSpacing; } - (void)setInternalSpacing:(CGFloat)internalSpacing { _internalSpacing = internalSpacing; - [self invalidateIntrinsicContentSize]; + [self refresh]; +} + + + +#pragma mark - Tint Color + +- (void)setTintColor:(UIColor *)tintColor +{ + [super setTintColor:tintColor]; + [self refresh]; } + + @end diff --git a/README.md b/README.md index f741f8a..304b28c 100644 --- a/README.md +++ b/README.md @@ -36,16 +36,11 @@ MONActivityIndicatorView is an awesome custom activity indicator view for iOS. ## Customization -### Default Property Values -* Animation delay : `delay = 0.2` -* Animation duration : `duration = 0.8` -* Number of circles : `numberOfCircles = 5` -* Circle's radius : `radius = 10` -* Circle's internal spacing : `internalSpacing = 5` -* Circle's background Color : `defaultColor = [UIColor lightGrayColor]` -### Custom Property Values +### Custom Properties +MONActivityIndicator is totally customizable: + ``` objective-c - (void)viewDidLoad { [super viewDidLoad]; @@ -56,17 +51,41 @@ MONActivityIndicatorView is an awesome custom activity indicator view for iOS. indicatorView.internalSpacing = 3; indicatorView.duration = 0.5; indicatorView.delay = 0.5 - indicatorView.center = self.view.center; - [self.view addSubview:indicatorView]; + ... [indicatorView startAnimating]; } ``` -### Custom Circle's Background Color -First, assign the `MONActivityIndicatorViewDelegate` protocol to a view controller. Then, implement the method `activityIndicatorView:circleBackgroundColorAtIndex:` +### Custom Dot Color +There are several ways to set the color of the dots in this component. + +**Option 1** + +MONActivityIndicatorView conforms to UIAppearance, so you can do this: + ``` objective-c -@interface ViewController : UIViewController +[[MONActivityIndicatorView appearance] setTintColor:[UIColor redColor]]; +``` + +or this: + +``` objective-c +MONActivityIndicatorView *indicatorView = [[MONActivityIndicatorView alloc] init]; +indicatorView.tintColor = [UIColor redColor]; +``` + + +**Option 2** +MONActivityIndicatorView supports IBInspectable, so you can set the tintColor in Interface Builder/Storyboard. + + +**Option 3** + +MONActivityIndicatorViewDelegate provides the method `activityIndicatorView:dotColorAtIndex:`, which you can implement in your delegate. + +``` objective-c +@interface ViewController : UIViewController @end @implementation ViewController @@ -76,24 +95,12 @@ First, assign the `MONActivityIndicatorViewDelegate` protocol to a view controll MONActivityIndicatorView *indicatorView = [[MONActivityIndicatorView alloc] init]; indicatorView.delegate = self; - indicatorView.numberOfCircles = 3; - indicatorView.radius = 20; - indicatorView.internalSpacing = 3; - indicatorView.duration = 0.5; - indicatorView.delay = 0.5 - indicatorView.center = self.view.center; - [self.view addSubview:indicatorView]; + ... [indicatorView startAnimating]; } -- (UIColor *)activityIndicatorView:(MONActivityIndicatorView *)activityIndicatorView - circleBackgroundColorAtIndex:(NSUInteger)index { - // For a random background color for a particular circle - CGFloat red = (arc4random() % 256)/255.0; - CGFloat green = (arc4random() % 256)/255.0; - CGFloat blue = (arc4random() % 256)/255.0; - CGFloat alpha = 1.0f; - return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; +- (UIColor *)activityIndicatorView:(MONActivityIndicatorView *)activityIndicatorView dotColorAtIndex:(NSUInteger)index { + return [UIColor redColor]; } @end