mirror of
https://bitbucket.org/vendoo/vendoo_v1.0.git
synced 2025-12-26 04:07:40 +00:00
246 lines
8.5 KiB
Objective-C
246 lines
8.5 KiB
Objective-C
//
|
|
// TYMActivityIndicatorView.m
|
|
// TYMActivityIndicatorView
|
|
//
|
|
// Created by Yiming Tang on 2/9/14.
|
|
// Copyright (c) 2014 - 2016 Yiming Tang. All rights reserved.
|
|
//
|
|
|
|
#import "TYMActivityIndicatorView.h"
|
|
|
|
@interface TYMActivityIndicatorView ()
|
|
|
|
@property (nonatomic) BOOL animating;
|
|
@property (nonatomic) UIImageView *spinnerImageView;
|
|
@property (nonatomic) UIImageView *backgroundImageView;
|
|
@property (nonatomic) NSMutableDictionary *backgroundImageStorage;
|
|
@property (nonatomic) NSMutableDictionary *spinnerImageStorage;
|
|
|
|
@end
|
|
|
|
@implementation TYMActivityIndicatorView
|
|
|
|
#pragma mark - Accessors
|
|
|
|
@synthesize activityIndicatorViewStyle = _activityIndicatorViewStyle;
|
|
@synthesize animating = _animating;
|
|
@synthesize backgroundImageView = _backgroundImageView;
|
|
@synthesize backgroundImageStorage = _backgroundImageStorage;
|
|
@synthesize spinnerImageView = _spinnerImageView;
|
|
@synthesize spinnerImageStorage = _spinnerImageStorage;
|
|
@synthesize clockwise = _clockwise;
|
|
@synthesize hidesWhenStopped = _hidesWhenStopped;
|
|
@synthesize fullRotationDuration = _fullRotationDuration;
|
|
@synthesize minProgressUnit = _minProgressUnit;
|
|
@synthesize progress = _progress;
|
|
|
|
- (UIImageView *)backgroundImageView {
|
|
if (!_backgroundImageView) {
|
|
_backgroundImageView = [[UIImageView alloc] initWithFrame:self.bounds];
|
|
_backgroundImageView.translatesAutoresizingMaskIntoConstraints = NO;
|
|
}
|
|
return _backgroundImageView;
|
|
}
|
|
|
|
|
|
- (UIImageView *)spinnerImageView {
|
|
if (!_spinnerImageView) {
|
|
_spinnerImageView = [[UIImageView alloc] initWithFrame:self.bounds];
|
|
_spinnerImageView.translatesAutoresizingMaskIntoConstraints = NO;
|
|
}
|
|
return _spinnerImageView;
|
|
}
|
|
|
|
|
|
- (NSMutableDictionary *)backgroundImageStorage {
|
|
if (!_backgroundImageStorage) {
|
|
_backgroundImageStorage = [NSMutableDictionary dictionary];
|
|
}
|
|
return _backgroundImageStorage;
|
|
}
|
|
|
|
|
|
- (NSMutableDictionary *)spinnerImageStorage {
|
|
if (!_spinnerImageStorage) {
|
|
_spinnerImageStorage = [NSMutableDictionary dictionary];
|
|
}
|
|
return _spinnerImageStorage;
|
|
}
|
|
|
|
|
|
- (void)setBackgroundImage:(UIImage *)backgroundImage forActivityIndicatorStyle:(TYMActivityIndicatorViewStyle)style {
|
|
[self.backgroundImageStorage setObject:backgroundImage forKey:@(style)];
|
|
}
|
|
|
|
|
|
- (UIImage *)backgroundImageForActivityIndicatorStyle:(TYMActivityIndicatorViewStyle)style {
|
|
UIImage *backgroundImage = [self.backgroundImageStorage objectForKey:@(style)];
|
|
if (!backgroundImage) {
|
|
backgroundImage = [[[self class] appearance] backgroundImageForActivityIndicatorStyle:style];
|
|
}
|
|
return backgroundImage;
|
|
}
|
|
|
|
|
|
- (void)setSpinnerImage:(UIImage *)spinnerImage forActivityIndicatorStyle:(TYMActivityIndicatorViewStyle)style {
|
|
[self.spinnerImageStorage setObject:spinnerImage forKey:@(style)];
|
|
}
|
|
|
|
|
|
- (UIImage *)spinnerImageForActivityIndicatorStyle:(TYMActivityIndicatorViewStyle)style {
|
|
UIImage *spinnerImage = [self.spinnerImageStorage objectForKey:@(style)];
|
|
if (!spinnerImage) {
|
|
spinnerImage = [[[self class] appearance] spinnerImageForActivityIndicatorStyle:style];
|
|
}
|
|
return spinnerImage;
|
|
}
|
|
|
|
|
|
- (void)setActivityIndicatorViewStyle:(TYMActivityIndicatorViewStyle)activityIndicatorViewStyle {
|
|
_activityIndicatorViewStyle = activityIndicatorViewStyle;
|
|
self.backgroundImageView.image = [self backgroundImageForActivityIndicatorStyle:activityIndicatorViewStyle];
|
|
self.spinnerImageView.image = [self spinnerImageForActivityIndicatorStyle:activityIndicatorViewStyle];
|
|
}
|
|
|
|
|
|
- (BOOL)isAnimating {
|
|
return self.animating;
|
|
}
|
|
|
|
|
|
#pragma mark - Class Methods
|
|
|
|
+ (void)initialize {
|
|
if (self == [TYMActivityIndicatorView class]) {
|
|
TYMActivityIndicatorView *appearance = [TYMActivityIndicatorView appearance];
|
|
[appearance setClockwise:YES];
|
|
[appearance setHidesWhenStopped:NO];
|
|
[appearance setFullRotationDuration:1.0];
|
|
[appearance setMinProgressUnit:0.01f];
|
|
[appearance setBackgroundImage:[UIImage imageNamed:@"TYMActivityIndicatorView.bundle/background-normal"] forActivityIndicatorStyle:TYMActivityIndicatorViewStyleNormal];
|
|
[appearance setSpinnerImage:[UIImage imageNamed:@"TYMActivityIndicatorView.bundle/spinner-normal"] forActivityIndicatorStyle:TYMActivityIndicatorViewStyleNormal];
|
|
[appearance setBackgroundImage:[UIImage imageNamed:@"TYMActivityIndicatorView.bundle/background-small"] forActivityIndicatorStyle:TYMActivityIndicatorViewStyleSmall];
|
|
[appearance setSpinnerImage:[UIImage imageNamed:@"TYMActivityIndicatorView.bundle/spinner-small"] forActivityIndicatorStyle:TYMActivityIndicatorViewStyleSmall];
|
|
[appearance setBackgroundImage:[UIImage imageNamed:@"TYMActivityIndicatorView.bundle/background-large"] forActivityIndicatorStyle:TYMActivityIndicatorViewStyleLarge];
|
|
[appearance setSpinnerImage:[UIImage imageNamed:@"TYMActivityIndicatorView.bundle/spinner-large"] forActivityIndicatorStyle:TYMActivityIndicatorViewStyleLarge];
|
|
}
|
|
}
|
|
|
|
|
|
#pragma mark - UIView
|
|
|
|
- (id)initWithCoder:(NSCoder *)aDecoder {
|
|
if ((self = [super initWithCoder:aDecoder])) {
|
|
[self initialize];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
|
|
- (id)initWithFrame:(CGRect)frame {
|
|
if ((self = [super initWithFrame:frame])) {
|
|
[self initialize];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
|
|
- (id)initWithActivityIndicatorStyle:(TYMActivityIndicatorViewStyle)style {
|
|
if ((self = [self initWithFrame:CGRectZero])) {
|
|
self.activityIndicatorViewStyle = style;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
|
|
- (CGSize)intrinsicContentSize {
|
|
return [self sizeThatFits:CGSizeZero];
|
|
}
|
|
|
|
|
|
- (CGSize)sizeThatFits:(CGSize)size {
|
|
CGSize backgroundImageSize = self.backgroundImageView.image.size;
|
|
CGSize indicatorImageSize = self.spinnerImageView.image.size;
|
|
|
|
return CGSizeMake(fmaxf(backgroundImageSize.width, indicatorImageSize.width), fmaxf(backgroundImageSize.height, indicatorImageSize.height));
|
|
}
|
|
|
|
|
|
#pragma mark - Public
|
|
|
|
- (void)startAnimating {
|
|
if (self.animating) return;
|
|
|
|
self.animating = YES;
|
|
self.hidden = NO;
|
|
CGFloat toValue = self.clockwise ? M_PI * 2 : -M_PI * 2;
|
|
|
|
[self rotateView:self.spinnerImageView from:0.0 to:toValue duration:self.fullRotationDuration repeatCount:HUGE_VALF forKey:@"rotation" removeAnimationOnCompletion:NO];
|
|
}
|
|
|
|
|
|
- (void)stopAnimating {
|
|
if (!self.animating) return;
|
|
|
|
self.animating = NO;
|
|
[self.spinnerImageView.layer removeAnimationForKey:@"rotation"];
|
|
if (self.hidesWhenStopped) {
|
|
self.hidden = YES;
|
|
}
|
|
}
|
|
|
|
|
|
- (void)setProgress:(CGFloat)progress {
|
|
if (progress < 0.0 || progress > 1.0) return;
|
|
if (fabs(_progress - progress) < self.minProgressUnit) return;
|
|
|
|
CGFloat fromValue = M_PI * 2 * _progress;
|
|
CGFloat toValue = M_PI * 2 * progress;
|
|
if (!self.clockwise) {
|
|
fromValue = -fromValue;
|
|
toValue = -toValue;
|
|
}
|
|
|
|
[self rotateView:self.spinnerImageView from:fromValue to:toValue duration:0.15f repeatCount:0 forKey:@"rotation" removeAnimationOnCompletion:NO];
|
|
|
|
_progress = progress;
|
|
}
|
|
|
|
|
|
#pragma mark - Private
|
|
|
|
- (void)initialize {
|
|
self.userInteractionEnabled = NO;
|
|
[self addSubview:self.backgroundImageView];
|
|
[self addSubview:self.spinnerImageView];
|
|
|
|
[self setupViewConstraints];
|
|
}
|
|
|
|
|
|
- (void)setupViewConstraints {
|
|
NSDictionary *views = @{
|
|
@"backgroundImageView": self.backgroundImageView,
|
|
@"spinnerImageView": self.spinnerImageView
|
|
};
|
|
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[backgroundImageView]|" options:kNilOptions metrics:nil views:views]];
|
|
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[backgroundImageView]|" options:kNilOptions metrics:nil views:views]];
|
|
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[spinnerImageView]|" options:kNilOptions metrics:nil views:views]];
|
|
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[spinnerImageView]|" options:kNilOptions metrics:nil views:views]];
|
|
}
|
|
|
|
|
|
- (void)rotateView:(UIView *)view from:(CGFloat)fromValue to:(CGFloat)toValue duration:(CGFloat)duration repeatCount:(CGFloat)repeatCount forKey:(NSString *)key removeAnimationOnCompletion:(BOOL)removeOnCompletion {
|
|
CABasicAnimation *rotationAnimation = [CABasicAnimation animation];
|
|
rotationAnimation.keyPath = @"transform.rotation.z";
|
|
rotationAnimation.fromValue = @(fromValue);
|
|
rotationAnimation.toValue = @(toValue);
|
|
rotationAnimation.duration = duration;
|
|
rotationAnimation.repeatCount = repeatCount;
|
|
rotationAnimation.removedOnCompletion = removeOnCompletion;
|
|
rotationAnimation.fillMode = kCAFillModeForwards;
|
|
[view.layer addAnimation:rotationAnimation forKey:key];
|
|
}
|
|
|
|
@end
|