[new downloader][ios] Updated circular progress.

This commit is contained in:
Ilya Grechuhin 2016-02-19 15:22:19 +03:00 committed by Sergey Yershov
parent 9dacca71c0
commit 372c6b7811
11 changed files with 72 additions and 87 deletions

View file

@ -4,6 +4,7 @@ typedef NS_ENUM(NSInteger, MWMCircularProgressState)
MWMCircularProgressStateNormal,
MWMCircularProgressStateSelected,
MWMCircularProgressStateProgress,
MWMCircularProgressStateSpinner,
MWMCircularProgressStateFailed,
MWMCircularProgressStateCompleted
};
@ -24,11 +25,9 @@ typedef NS_ENUM(NSInteger, MWMCircularProgressState)
- (void)setImage:(nonnull UIImage *)image forState:(MWMCircularProgressState)state;
- (void)setColor:(nonnull UIColor *)color forState:(MWMCircularProgressState)state;
- (void)setInvertColor:(BOOL)invertColor;
- (nonnull instancetype)init __attribute__((unavailable("init is not available")));
- (nonnull instancetype)initWithParentView:(nonnull UIView *)parentView;
- (void)reset;
- (void)startSpinner:(BOOL)isInvert;
- (void)stopSpinner;
@end

View file

@ -16,18 +16,24 @@
if (self)
{
[[NSBundle mainBundle] loadNibNamed:self.class.className owner:self options:nil];
[parentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
[parentView addSubview:self.rootView];
[self reset];
self.state = MWMCircularProgressStateNormal;
}
return self;
}
- (void)dealloc
{
[self.rootView removeFromSuperview];
}
- (void)reset
{
_progress = 0.;
[self.rootView updatePath:0.];
self.nextProgressToAnimate = nil;
self.state = MWMCircularProgressStateNormal;
}
- (void)setImage:(nonnull UIImage *)image forState:(MWMCircularProgressState)state
@ -40,17 +46,9 @@
[self.rootView setColor:color forState:state];
}
#pragma mark - Spinner
- (void)startSpinner:(BOOL)isInvert
- (void)setInvertColor:(BOOL)invertColor
{
[self reset];
[self.rootView startSpinner:isInvert];
}
- (void)stopSpinner
{
[self.rootView stopSpinner];
self.rootView.isInvertColor = invertColor;
}
#pragma mark - Animation
@ -77,9 +75,10 @@
{
if (progress <= _progress)
{
[self reset];
self.state = MWMCircularProgressStateSpinner;
return;
}
self.rootView.state = MWMCircularProgressStateProgress;
if (self.rootView.animating)
{
if (progress > self.nextProgressToAnimate.floatValue)
@ -87,14 +86,21 @@
}
else
{
[self.rootView animateFromValue:_progress toValue:progress];
dispatch_async(dispatch_get_main_queue(), ^
{
[self.rootView animateFromValue:self->_progress toValue:progress];
});
_progress = progress;
}
}
- (void)setState:(MWMCircularProgressState)state
{
self.rootView.state = state;
dispatch_async(dispatch_get_main_queue(), ^
{
[self reset];
self.rootView.state = state;
});
}
- (MWMCircularProgressState)state

View file

@ -3,6 +3,7 @@
@property (nonatomic, readonly) BOOL animating;
@property (nonatomic) MWMCircularProgressState state;
@property (nonatomic) BOOL isInvertColor;
- (nonnull instancetype)initWithFrame:(CGRect)frame __attribute__((unavailable("initWithFrame is not available")));
- (nonnull instancetype)init __attribute__((unavailable("init is not available")));
@ -13,7 +14,5 @@
- (void)animateFromValue:(CGFloat)fromValue toValue:(CGFloat)toValue;
- (void)updatePath:(CGFloat)progress;
- (void)startSpinner:(BOOL)isInvert;
- (void)stopSpinner;
@end

View file

@ -56,6 +56,7 @@ static inline CGFloat angleWithProgress(CGFloat progress)
[self setColor:clearColor forState:MWMCircularProgressStateNormal];
[self setColor:clearColor forState:MWMCircularProgressStateSelected];
[self setColor:progressColor forState:MWMCircularProgressStateProgress];
[self setColor:progressColor forState:MWMCircularProgressStateSpinner];
[self setColor:clearColor forState:MWMCircularProgressStateFailed];
[self setColor:clearColor forState:MWMCircularProgressStateCompleted];
}
@ -97,30 +98,20 @@ static inline CGFloat angleWithProgress(CGFloat progress)
self.progressLayer.strokeColor = self.progressLayerColor;
CGRect rect = CGRectInset(self.bounds, kLineWidth, kLineWidth);
self.backgroundLayer.path = [UIBezierPath bezierPathWithOvalInRect:rect].CGPath;
UIImage * normalImage = nil;
switch (self.state)
{
case MWMCircularProgressStateNormal:
normalImage = self.images[@(MWMCircularProgressStateNormal)];
self.button.coloring = MWMButtonColoringBlack;
break;
case MWMCircularProgressStateSelected:
normalImage = self.images[@(MWMCircularProgressStateSelected)];
self.button.coloring = MWMButtonColoringBlue;
break;
case MWMCircularProgressStateProgress:
normalImage = self.images[@(MWMCircularProgressStateProgress)];
self.button.coloring = MWMButtonColoringBlue;
break;
case MWMCircularProgressStateSpinner:
case MWMCircularProgressStateFailed:
normalImage = self.images[@(MWMCircularProgressStateFailed)];
self.button.coloring = MWMButtonColoringBlue;
break;
case MWMCircularProgressStateCompleted:
normalImage = self.images[@(MWMCircularProgressStateCompleted)];
self.button.coloring = MWMButtonColoringBlue;
break;
}
UIImage * normalImage = self.images[@(self.state)];
[self.button setImage:normalImage forState:UIControlStateNormal];
}
@ -144,23 +135,20 @@ static inline CGFloat angleWithProgress(CGFloat progress)
#pragma mark - Spinner
- (void)startSpinner:(BOOL)isInvert
- (void)startSpinner
{
if (!self.spinner.hidden)
return;
self.spinner.hidden = NO;
dispatch_async(dispatch_get_main_queue(), ^
{
self.backgroundLayer.hidden = self.progressLayer.hidden = YES;
NSUInteger const animationImagesCount = 12;
NSMutableArray * animationImages = [NSMutableArray arrayWithCapacity:animationImagesCount];
NSString * postfix = ([UIColor isNightMode] && !isInvert) || (![UIColor isNightMode] && isInvert) ? @"dark" : @"light";
for (NSUInteger i = 0; i < animationImagesCount; ++i)
animationImages[i] = [UIImage imageNamed:[NSString stringWithFormat:@"Spinner_%@_%@", @(i+1), postfix]];
self.backgroundLayer.hidden = self.progressLayer.hidden = YES;
NSUInteger const animationImagesCount = 12;
NSMutableArray * animationImages = [NSMutableArray arrayWithCapacity:animationImagesCount];
NSString * postfix = ([UIColor isNightMode] && !self.isInvertColor) || (![UIColor isNightMode] && self.isInvertColor) ? @"dark" : @"light";
for (NSUInteger i = 0; i < animationImagesCount; ++i)
animationImages[i] = [UIImage imageNamed:[NSString stringWithFormat:@"Spinner_%@_%@", @(i+1), postfix]];
self.spinner.animationImages = animationImages;
[self.spinner startAnimating];
});
self.spinner.animationImages = animationImages;
[self.spinner startAnimating];
}
- (void)stopSpinner
@ -168,29 +156,23 @@ static inline CGFloat angleWithProgress(CGFloat progress)
if (self.spinner.hidden)
return;
self.spinner.hidden = YES;
dispatch_async(dispatch_get_main_queue(), ^
{
self.backgroundLayer.hidden = self.progressLayer.hidden = NO;
[self.spinner.layer removeAllAnimations];
});
self.backgroundLayer.hidden = self.progressLayer.hidden = NO;
[self.spinner.layer removeAllAnimations];
}
#pragma mark - Animation
- (void)animateFromValue:(CGFloat)fromValue toValue:(CGFloat)toValue
{
dispatch_async(dispatch_get_main_queue(), ^
{
[self updatePath:toValue];
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.duration = kDefaultAnimationDuration;
animation.repeatCount = 1;
animation.fromValue = @(fromValue / toValue);
animation.toValue = @1;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.delegate = self.owner;
[self.progressLayer addAnimation:animation forKey:kAnimationKey];
});
[self updatePath:toValue];
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.duration = kDefaultAnimationDuration;
animation.repeatCount = 1;
animation.fromValue = @(fromValue / toValue);
animation.toValue = @1;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.delegate = self.owner;
[self.progressLayer addAnimation:animation forKey:kAnimationKey];
}
#pragma mark - Properties
@ -199,6 +181,10 @@ static inline CGFloat angleWithProgress(CGFloat progress)
{
if (_state == state)
return;
if (state == MWMCircularProgressStateSpinner)
[self startSpinner];
else if (_state == MWMCircularProgressStateSpinner)
[self stopSpinner];
_state = state;
[self refreshProgress];
}

View file

@ -40,20 +40,21 @@
{
[[NSBundle mainBundle] loadNibNamed:self.class.className owner:self options:nil];
[parentView addSubview:self.rootView];
self.progressView = [[MWMCircularProgress alloc] initWithParentView:self.progressViewWrapper];
self.progressView.delegate = self;
[self setupProgressImages];
[self setupProgressView];
self.delegate = delegate;
[self showRequest];
}
return self;
}
- (void)setupProgressImages
- (void)setupProgressView
{
self.progressView = [[MWMCircularProgress alloc] initWithParentView:self.progressViewWrapper];
self.progressView.delegate = self;
[self.progressView setImage:[UIImage imageNamed:@"ic_download"] forState:MWMCircularProgressStateNormal];
[self.progressView setImage:[UIImage imageNamed:@"ic_download"] forState:MWMCircularProgressStateSelected];
[self.progressView setImage:[UIImage imageNamed:@"ic_close_spinner"] forState:MWMCircularProgressStateProgress];
[self.progressView setImage:[UIImage imageNamed:@"ic_close_spinner"] forState:MWMCircularProgressStateSpinner];
[self.progressView setImage:[UIImage imageNamed:@"ic_download_error"] forState:MWMCircularProgressStateFailed];
[self.progressView setImage:[UIImage imageNamed:@"ic_check"] forState:MWMCircularProgressStateCompleted];
}
@ -112,7 +113,6 @@
- (void)setDownloadFailed
{
self.progressView.state = MWMCircularProgressStateFailed;
[self.progressView stopSpinner];
}
#pragma mark - MWMCircularProgressDelegate
@ -125,7 +125,7 @@
if (progress.state == MWMCircularProgressStateFailed)
{
s.RetryDownloadNode(m_countryId);
[self.progressView startSpinner:NO];
self.progressView.state = MWMCircularProgressStateSpinner;
}
else
{
@ -141,9 +141,8 @@
[[Statistics instance] logEvent:kStatEventName(kStatDownloadRequest, kStatDownloadMap)];
[MapsAppDelegate downloadNode:m_countryId alertController:self.delegate.alertController onSuccess:^
{
self.progressView.progress = 0.0;
[self showRequest];
[self.progressView startSpinner:NO];
self.progressView.state = MWMCircularProgressStateSpinner;
}];
}

View file

@ -99,7 +99,8 @@ using namespace osm;
{
self.spinnerView.hidden = NO;
self.spinner = [[MWMCircularProgress alloc] initWithParentView:self.spinnerView];
[self.spinner startSpinner:YES];
[self.spinner setInvertColor:YES];
self.spinner.state = MWMCircularProgressStateSpinner;
self.loginTextField.enabled = NO;
self.passwordTextField.enabled = NO;
self.forgotButton.enabled = NO;
@ -109,8 +110,6 @@ using namespace osm;
- (void)stopSpinner
{
self.spinnerView.hidden = YES;
[self.spinnerView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
[self.spinner stopSpinner];
self.spinner = nil;
self.loginTextField.enabled = YES;
self.passwordTextField.enabled = YES;

View file

@ -116,15 +116,14 @@ NSString * getVerifier(NSString * urlString)
{
self.spinnerView.hidden = NO;
self.spinner = [[MWMCircularProgress alloc] initWithParentView:self.spinnerView];
[self.spinner startSpinner:YES];
[self.spinner setInvertColor:YES];
self.spinner.state = MWMCircularProgressStateSpinner;
self.webView.userInteractionEnabled = NO;
}
- (void)stopSpinner
{
self.spinnerView.hidden = YES;
[self.spinnerView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
[self.spinner stopSpinner];
self.spinner = nil;
self.webView.userInteractionEnabled = YES;
}

View file

@ -163,7 +163,6 @@ extern NSString * const kTTSStatusWasChangedNotification;
{
[self.routePreview stateError];
self.activeRouteTypeButton.state = MWMCircularProgressStateFailed;
[self.activeRouteTypeButton stopSpinner];
}
- (void)updateDashboard
@ -248,7 +247,7 @@ extern NSString * const kTTSStatusWasChangedNotification;
[[Statistics instance]
logEvent:kStatPointToPoint
withParameters:@{kStatAction : kStatChangeRoutingMode, kStatValue : kStatPedestrian}];
[self.routePreview.vehicleProgressView stopSpinner];
self.routePreview.vehicleProgressView.state = MWMCircularProgressStateNormal;
type = routing::RouterType::Pedestrian;
}
else
@ -256,7 +255,7 @@ extern NSString * const kTTSStatusWasChangedNotification;
[[Statistics instance]
logEvent:kStatPointToPoint
withParameters:@{kStatAction : kStatChangeRoutingMode, kStatValue : kStatVehicle}];
[self.routePreview.pedestrianProgressView stopSpinner];
self.routePreview.pedestrianProgressView.state = MWMCircularProgressStateNormal;
type = routing::RouterType::Vehicle;
}
f.CloseRouting();
@ -265,7 +264,7 @@ extern NSString * const kTTSStatusWasChangedNotification;
[self.routePreview selectProgress:progress];
if (!self.delegate.isPossibleToBuildRoute)
return;
[progress startSpinner:NO];
progress.state = MWMCircularProgressStateSpinner;
[self.delegate buildRoute];
}
@ -336,7 +335,7 @@ extern NSString * const kTTSStatusWasChangedNotification;
[self removePanel:self.nextTurnPanel];
// [self removePanel:self.lanesPanel];
[self setupActualRoute];
[self.activeRouteTypeButton startSpinner:NO];
self.activeRouteTypeButton.state = MWMCircularProgressStateSpinner;
}
- (void)showStateReady

View file

@ -57,12 +57,14 @@ static CGFloat const kAdditionalHeight = 20.;
[self.pedestrianProgressView setImage:[UIImage imageNamed:@"ic_walk"] forState:MWMCircularProgressStateFailed];
[self.pedestrianProgressView setImage:[UIImage imageNamed:@"ic_walk"] forState:MWMCircularProgressStateSelected];
[self.pedestrianProgressView setImage:[UIImage imageNamed:@"ic_walk"] forState:MWMCircularProgressStateProgress];
[self.pedestrianProgressView setImage:[UIImage imageNamed:@"ic_walk"] forState:MWMCircularProgressStateSpinner];
[self.pedestrianProgressView setImage:[UIImage imageNamed:@"ic_walk"] forState:MWMCircularProgressStateCompleted];
self.vehicleProgressView = [[MWMCircularProgress alloc] initWithParentView:self.vehicle];
[self.vehicleProgressView setImage:[UIImage imageNamed:@"ic_drive"] forState:MWMCircularProgressStateNormal];
[self.vehicleProgressView setImage:[UIImage imageNamed:@"ic_drive"] forState:MWMCircularProgressStateFailed];
[self.vehicleProgressView setImage:[UIImage imageNamed:@"ic_drive"] forState:MWMCircularProgressStateSelected];
[self.vehicleProgressView setImage:[UIImage imageNamed:@"ic_drive"] forState:MWMCircularProgressStateProgress];
[self.vehicleProgressView setImage:[UIImage imageNamed:@"ic_drive"] forState:MWMCircularProgressStateSpinner];
[self.vehicleProgressView setImage:[UIImage imageNamed:@"ic_drive"] forState:MWMCircularProgressStateCompleted];
}
@ -99,8 +101,8 @@ static CGFloat const kAdditionalHeight = 20.;
- (void)statePrepare
{
[self.pedestrianProgressView stopSpinner];
[self.vehicleProgressView stopSpinner];
self.pedestrianProgressView.state = MWMCircularProgressStateNormal;
self.vehicleProgressView.state = MWMCircularProgressStateNormal;
self.arrowImageView.transform = CGAffineTransformMakeRotation(M_PI);
self.goButton.hidden = NO;
self.goButton.enabled = NO;
@ -193,7 +195,6 @@ static CGFloat const kAdditionalHeight = 20.;
- (void)deselectPedestrian
{
self.pedestrianProgressView.state = MWMCircularProgressStateNormal;
[self.pedestrianProgressView stopSpinner];
}
- (void)selectProgress:(MWMCircularProgress *)progress;
@ -213,7 +214,6 @@ static CGFloat const kAdditionalHeight = 20.;
- (void)deselectVehicle
{
self.vehicleProgressView.state = MWMCircularProgressStateNormal;
[self.vehicleProgressView stopSpinner];
}
- (void)layoutSubviews

View file

@ -72,14 +72,13 @@
{
self.spinnerView.hidden = NO;
self.spinner = [[MWMCircularProgress alloc] initWithParentView:self.spinnerView];
[self.spinner startSpinner:YES];
[self.spinner setInvertColor:YES];
self.spinner.state = MWMCircularProgressStateSpinner;
}
- (void)stopSpinner
{
self.spinnerView.hidden = YES;
[self.spinnerView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
[self.spinner stopSpinner];
self.spinner = nil;
}

View file

@ -153,7 +153,7 @@ using namespace storage;
{
self.downloadButton.hidden = YES;
self.progressWrapper.hidden = NO;
[self.progressView startSpinner:NO];
self.progressView.state = MWMCircularProgressStateSpinner;
}
#pragma mark - MWMFrameworkDrapeObserver