From b349b456a50c12826600b1546315e01f65631560 Mon Sep 17 00:00:00 2001 From: Gunnar Herzog Date: Wed, 26 Jun 2013 17:06:45 +0200 Subject: [PATCH] Add option to display progress bar on launch image --- .../GCOLaunchImageTransition/GCOAppDelegate.m | 40 +++++++- .../GCOLaunchImageTransition.h | 15 ++- .../GCOLaunchImageTransition.m | 93 +++++++++++++++---- 3 files changed, 128 insertions(+), 20 deletions(-) diff --git a/Example Project/GCOLaunchImageTransition/GCOAppDelegate.m b/Example Project/GCOLaunchImageTransition/GCOAppDelegate.m index cd37f08..238b63d 100644 --- a/Example Project/GCOLaunchImageTransition/GCOAppDelegate.m +++ b/Example Project/GCOLaunchImageTransition/GCOAppDelegate.m @@ -32,12 +32,19 @@ #import "GCOLaunchImageTransition.h" +@interface GCOAppDelegate () + +@property (nonatomic, assign) float progress; + +@end + + @implementation GCOAppDelegate - (void)applicationDidBecomeActive:(UIApplication *)application { // Choose a demo by setting values from 1 to 3 - NSUInteger demo = 3; + NSUInteger demo = 4; switch( demo ) { @@ -70,9 +77,40 @@ - (void)applicationDidBecomeActive:(UIApplication *)application break; } + + case 4: + { + GCOLaunchImageTransition *transition = [GCOLaunchImageTransition transitionWithInfiniteDelayAndDuration:0.5 style:GCOLaunchImageTransitionAnimationStyleZoomIn progressBarPosition:CGPointMake( 0.5, 0.9 ) progressBarWidth:0.5]; + transition.progressLabel.font = [UIFont boldSystemFontOfSize:16]; + transition.progressLabel.textColor = [UIColor purpleColor]; + transition.progressView.trackTintColor = [UIColor lightGrayColor]; + transition.progressView.progressTintColor = [UIColor purpleColor]; + + self.progress = 0.0; + NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(updateLaunchProgress:) userInfo:nil repeats:YES]; + [timer fire]; + + [self performSelector:@selector(finishLaunchImageTransitionNow) withObject:nil afterDelay:6.0]; + break; + } } } + +- (void)updateLaunchProgress:(NSTimer *)timer +{ + NSDictionary *userInfo = @{GCOLaunchImageTransitionProgressValue : @(self.progress), GCOLaunchImageTransitionProgressText:[NSString stringWithFormat:@"%u %%", (int)(self.progress * 100)]}; + [[NSNotificationCenter defaultCenter] postNotificationName:GCOLaunchImageTransitionProgressNotification object:nil userInfo:userInfo]; + + if (self.progress >= 1.0f) + { + [timer invalidate]; + } + + self.progress += 0.002f; +} + + - (void)finishLaunchImageTransitionNow { [[NSNotificationCenter defaultCenter] postNotificationName:GCOLaunchImageTransitionHideNotification object:self]; diff --git a/GCOLaunchImageTransition/GCOLaunchImageTransition.h b/GCOLaunchImageTransition/GCOLaunchImageTransition.h index 7f70fac..9e44fe4 100644 --- a/GCOLaunchImageTransition/GCOLaunchImageTransition.h +++ b/GCOLaunchImageTransition/GCOLaunchImageTransition.h @@ -33,6 +33,9 @@ #define GCOLaunchImageTransitionNearInfiniteDelay DBL_MAX extern NSString* const GCOLaunchImageTransitionHideNotification; +extern NSString* const GCOLaunchImageTransitionProgressNotification; +extern NSString* const GCOLaunchImageTransitionProgressValue; +extern NSString* const GCOLaunchImageTransitionProgressText; typedef enum GCOLaunchImageTransitionAnimationStyle_ { @@ -43,19 +46,25 @@ typedef enum GCOLaunchImageTransitionAnimationStyle_ @interface GCOLaunchImageTransition : NSObject +@property( nonatomic, strong ) UIProgressView* progressView; + +@property( nonatomic, strong ) UILabel* progressLabel; + // Create transition with a given style that begins immediately -+ (void)transitionWithDuration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style; ++ (instancetype)transitionWithDuration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style; // Create transition with an near-infinite delay that requires manual dismissal via notification like this: // [[NSNotificationCenter defaultCenter] postNotificationName:GCOLaunchImageTransitionHideNotification object:self];) -+ (void)transitionWithInfiniteDelayAndDuration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style; ++ (instancetype)transitionWithInfiniteDelayAndDuration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style; // Create fully customizable transition including an optional activity indicator // The 'activityIndicatorPosition' is a percentage value ('CGPointMake( 0.5, 0.5 )' being the center) // See https://github.com/gonecoding/GCOLaunchImageTransition for more documentation -+ (void)transitionWithDelay:(NSTimeInterval)delay duration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style activityIndicatorPosition:(CGPoint)activityIndicatorPosition activityIndicatorStyle:(UIActivityIndicatorViewStyle)activityIndicatorStyle; ++ (instancetype)transitionWithDelay:(NSTimeInterval)delay duration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style activityIndicatorPosition:(CGPoint)activityIndicatorPosition activityIndicatorStyle:(UIActivityIndicatorViewStyle)activityIndicatorStyle; + ++ (instancetype)transitionWithInfiniteDelayAndDuration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style progressBarPosition:(CGPoint)progressBarPosition progressBarWidth:(CGFloat)progressBarWidth; @end diff --git a/GCOLaunchImageTransition/GCOLaunchImageTransition.m b/GCOLaunchImageTransition/GCOLaunchImageTransition.m index c526271..ed3c1f2 100644 --- a/GCOLaunchImageTransition/GCOLaunchImageTransition.m +++ b/GCOLaunchImageTransition/GCOLaunchImageTransition.m @@ -31,6 +31,9 @@ #import "GCOLaunchImageTransition.h" NSString* const GCOLaunchImageTransitionHideNotification = @"GCOLaunchImageTransitionHideNotification"; +NSString* const GCOLaunchImageTransitionProgressNotification = @"GCOLaunchImageTransitionProgressNotification"; +NSString* const GCOLaunchImageTransitionProgressValue = @"GCOLaunchImageTransitionProgressValue"; +NSString* const GCOLaunchImageTransitionProgressText = @"GCOLaunchImageTransitionProgressText"; @interface GCOLaunchImageTransition () @@ -45,32 +48,50 @@ @interface GCOLaunchImageTransition () @implementation GCOLaunchImageTransition -+ (void)transitionWithDuration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style ++ (instancetype)transitionWithDuration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style { - [self transitionWithDelay:0.0 duration:duration style:style activityIndicatorPosition:CGPointZero activityIndicatorStyle:0]; + return [self transitionWithDelay:0.0 duration:duration style:style activityIndicatorPosition:CGPointZero activityIndicatorStyle:0]; } -+ (void)transitionWithInfiniteDelayAndDuration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style + ++ (instancetype)transitionWithInfiniteDelayAndDuration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style { - [self transitionWithDelay:GCOLaunchImageTransitionNearInfiniteDelay duration:duration style:style activityIndicatorPosition:CGPointZero activityIndicatorStyle:0]; + return [self transitionWithDelay:GCOLaunchImageTransitionNearInfiniteDelay duration:duration style:style activityIndicatorPosition:CGPointZero activityIndicatorStyle:0]; } -+ (void)transitionWithDelay:(NSTimeInterval)delay duration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style activityIndicatorPosition:(CGPoint)activityIndicatorPosition activityIndicatorStyle:(UIActivityIndicatorViewStyle)activityIndicatorStyle + ++ (instancetype)transitionWithDelay:(NSTimeInterval)delay duration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style activityIndicatorPosition:(CGPoint)activityIndicatorPosition activityIndicatorStyle:(UIActivityIndicatorViewStyle)activityIndicatorStyle { - static dispatch_once_t onceToken; - - dispatch_once( &onceToken, ^ - { - UIWindow* window = [UIApplication sharedApplication].keyWindow; - GCOLaunchImageTransition* transitionView = [[self alloc] initWithAnimationDelay:delay animationDuration:duration style:style activityIndicatorPosition:activityIndicatorPosition activityIndicatorStyle:activityIndicatorStyle]; - - [window addSubview:transitionView.imageView]; - }); + return [self transitionWithDelay:delay duration:duration style:style activityIndicatorPosition:activityIndicatorPosition activityIndicatorStyle:activityIndicatorStyle progressBarPosition:CGPointZero progressBarWidth:0.0f]; } + ++ (instancetype)transitionWithInfiniteDelayAndDuration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style progressBarPosition:(CGPoint)progressBarPosition progressBarWidth:(CGFloat)progressBarWidth +{ + return [self transitionWithDelay:GCOLaunchImageTransitionNearInfiniteDelay duration:duration style:style activityIndicatorPosition:CGPointZero activityIndicatorStyle:0 progressBarPosition:progressBarPosition progressBarWidth:progressBarWidth]; +} + + ++ (instancetype)transitionWithDelay:(NSTimeInterval)delay duration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style activityIndicatorPosition:(CGPoint)activityIndicatorPosition activityIndicatorStyle:(UIActivityIndicatorViewStyle)activityIndicatorStyle progressBarPosition:(CGPoint)progressBarPosition progressBarWidth:(CGFloat)progressBarWidth +{ + static GCOLaunchImageTransition *transitionView = nil; + static dispatch_once_t onceToken; + + dispatch_once( &onceToken, ^ + { + UIWindow* window = [UIApplication sharedApplication].keyWindow; + transitionView = [[self alloc] initWithAnimationDelay:delay animationDuration:duration style:style activityIndicatorPosition:activityIndicatorPosition activityIndicatorStyle:activityIndicatorStyle progressBarPosition:progressBarPosition progressBarWidth:progressBarWidth]; + + [window addSubview:transitionView.imageView]; + }); + + return transitionView; +} + + #pragma mark - Object life cycle -- (id)initWithAnimationDelay:(NSTimeInterval)delay animationDuration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style activityIndicatorPosition:(CGPoint)activityIndicatorPosition activityIndicatorStyle:(UIActivityIndicatorViewStyle)activityIndicatorStyle +- (id)initWithAnimationDelay:(NSTimeInterval)delay animationDuration:(NSTimeInterval)duration style:(GCOLaunchImageTransitionAnimationStyle)style activityIndicatorPosition:(CGPoint)activityIndicatorPosition activityIndicatorStyle:(UIActivityIndicatorViewStyle)activityIndicatorStyle progressBarPosition:(CGPoint)progressBarPosition progressBarWidth:(CGFloat)progressBarWidth { self = [super init]; @@ -99,6 +120,28 @@ - (id)initWithAnimationDelay:(NSTimeInterval)delay animationDuration:(NSTimeInte [self.activityIndicatorView startAnimating]; } + else if ( !CGPointEqualToPoint( progressBarPosition, CGPointZero) ) + { + self.progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; + + CGSize size = self.imageView.bounds.size; + + CGRect frame = self.progressView.frame; + frame.size.width = size.width * progressBarWidth; + self.progressView.frame = frame; + + self.progressView.center = CGPointMake( size.width * progressBarPosition.x, size.height * progressBarPosition.y ); + + self.progressLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + self.progressLabel.lineBreakMode = UILineBreakModeMiddleTruncation; + self.progressLabel.numberOfLines = 1; + self.progressLabel.backgroundColor = [UIColor clearColor]; + + [self.imageView addSubview:self.progressView]; + [self.imageView addSubview:self.progressLabel]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleProgressNotification:) name:GCOLaunchImageTransitionProgressNotification object:nil]; + } // Start transition animation with given delay [self performSelector:@selector(performViewAnimations) withObject:nil afterDelay:self.delay]; @@ -115,7 +158,7 @@ - (void)dealloc #pragma mark - View animations - (void)performViewAnimations -{ +{ if( self.activityIndicatorView ) { [self.activityIndicatorView stopAnimating]; @@ -140,8 +183,26 @@ - (void)performViewAnimations }]; } + #pragma mark - Handle notifications +- (void)handleProgressNotification:(NSNotification*)notification +{ + if( [notification.name isEqualToString:GCOLaunchImageTransitionProgressNotification] ) + { + float progress = [notification.userInfo[GCOLaunchImageTransitionProgressValue] floatValue]; + self.progressView.progress = progress; + + self.progressLabel.text = notification.userInfo[GCOLaunchImageTransitionProgressText]; + + CGRect frame = self.progressLabel.frame; + frame.size = [self.progressLabel sizeThatFits:CGSizeMake(frame.size.width, 10000)]; + frame.origin = CGPointMake(self.progressView.frame.size.width - frame.size.width / 2, CGRectGetMaxY(self.progressView.frame) + 8); + self.progressLabel.frame = frame; + } +} + + - (void)handleHideNotification:(NSNotification*)notification { if( [notification.name isEqualToString:GCOLaunchImageTransitionHideNotification] )