Stop flickering in iOS network activity indicator by introducing a small delay before hiding it
Based on an idea from Jesse Rusak -> http://github.com/MindSea/asi-http-request/commit/f346f7f9de333501f732404323e8f73e911fbeea
Showing
2 changed files
with
39 additions
and
16 deletions
@@ -725,9 +725,15 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | @@ -725,9 +725,15 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; | ||
725 | #pragma mark network activity | 725 | #pragma mark network activity |
726 | 726 | ||
727 | + (BOOL)isNetworkInUse; | 727 | + (BOOL)isNetworkInUse; |
728 | -#if TARGET_OS_IPHONE | 728 | + |
729 | + (void)setShouldUpdateNetworkActivityIndicator:(BOOL)shouldUpdate; | 729 | + (void)setShouldUpdateNetworkActivityIndicator:(BOOL)shouldUpdate; |
730 | -#endif | 730 | + |
731 | +// Shows the network activity spinner thing on iOS. You may wish to override this to do something else in Mac projects | ||
732 | ++ (void)showNetworkActivityIndicator; | ||
733 | + | ||
734 | +// Hides the network activity spinner thing on iOS | ||
735 | ++ (void)hideNetworkActivityIndicator; | ||
736 | + | ||
731 | 737 | ||
732 | #pragma mark miscellany | 738 | #pragma mark miscellany |
733 | 739 |
@@ -23,7 +23,7 @@ | @@ -23,7 +23,7 @@ | ||
23 | 23 | ||
24 | 24 | ||
25 | // Automatically set on build | 25 | // Automatically set on build |
26 | -NSString *ASIHTTPRequestVersion = @"v1.7-42 2010-08-18"; | 26 | +NSString *ASIHTTPRequestVersion = @"v1.7-53 2010-08-18"; |
27 | 27 | ||
28 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; | 28 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; |
29 | 29 | ||
@@ -130,10 +130,12 @@ static id <ASICacheDelegate> defaultCache = nil; | @@ -130,10 +130,12 @@ static id <ASICacheDelegate> defaultCache = nil; | ||
130 | // Used for tracking when requests are using the network | 130 | // Used for tracking when requests are using the network |
131 | static unsigned int runningRequestCount = 0; | 131 | static unsigned int runningRequestCount = 0; |
132 | 132 | ||
133 | -#if TARGET_OS_IPHONE | 133 | + |
134 | -// Use [ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:NO] if you want to manage it yourself | 134 | +// You can use [ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:NO] if you want to manage it yourself |
135 | +// Alternatively, override showNetworkActivityIndicator / hideNetworkActivityIndicator | ||
136 | +// By default this does nothing on Mac OS X, but again override the above methods for a different behaviour | ||
135 | static BOOL shouldUpdateNetworkActivityIndicator = YES; | 137 | static BOOL shouldUpdateNetworkActivityIndicator = YES; |
136 | -#endif | 138 | + |
137 | 139 | ||
138 | //**Queue stuff**/ | 140 | //**Queue stuff**/ |
139 | 141 | ||
@@ -2990,11 +2992,12 @@ static NSOperationQueue *sharedQueue = nil; | @@ -2990,11 +2992,12 @@ static NSOperationQueue *sharedQueue = nil; | ||
2990 | 2992 | ||
2991 | if ([self readStreamIsScheduled]) { | 2993 | if ([self readStreamIsScheduled]) { |
2992 | runningRequestCount--; | 2994 | runningRequestCount--; |
2993 | - #if TARGET_OS_IPHONE | ||
2994 | if (shouldUpdateNetworkActivityIndicator && runningRequestCount == 0) { | 2995 | if (shouldUpdateNetworkActivityIndicator && runningRequestCount == 0) { |
2995 | - [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; | 2996 | + // Wait half a second before turning off the indicator |
2997 | + // This can prevent flicker when you have a single request finish and then immediately start another request | ||
2998 | + // We will cancel hiding the activity indicator if we start again | ||
2999 | + [[self class] performSelector:@selector(hideNetworkActivityIndicator) withObject:nil afterDelay:0.5]; | ||
2996 | } | 3000 | } |
2997 | - #endif | ||
2998 | } | 3001 | } |
2999 | 3002 | ||
3000 | [self setReadStreamIsScheduled:NO]; | 3003 | [self setReadStreamIsScheduled:NO]; |
@@ -3014,11 +3017,10 @@ static NSOperationQueue *sharedQueue = nil; | @@ -3014,11 +3017,10 @@ static NSOperationQueue *sharedQueue = nil; | ||
3014 | 3017 | ||
3015 | [connectionsLock lock]; | 3018 | [connectionsLock lock]; |
3016 | runningRequestCount++; | 3019 | runningRequestCount++; |
3017 | - #if TARGET_OS_IPHONE | ||
3018 | if (shouldUpdateNetworkActivityIndicator) { | 3020 | if (shouldUpdateNetworkActivityIndicator) { |
3019 | - [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; | 3021 | + [NSObject cancelPreviousPerformRequestsWithTarget:[self class] selector:@selector(hideNetworkActivityIndicator) object:nil]; |
3022 | + [[self class] showNetworkActivityIndicator]; | ||
3020 | } | 3023 | } |
3021 | - #endif | ||
3022 | [connectionsLock unlock]; | 3024 | [connectionsLock unlock]; |
3023 | 3025 | ||
3024 | // Reset the timeout | 3026 | // Reset the timeout |
@@ -3028,17 +3030,19 @@ static NSOperationQueue *sharedQueue = nil; | @@ -3028,17 +3030,19 @@ static NSOperationQueue *sharedQueue = nil; | ||
3028 | } | 3030 | } |
3029 | } | 3031 | } |
3030 | 3032 | ||
3033 | + | ||
3031 | - (void)unscheduleReadStream | 3034 | - (void)unscheduleReadStream |
3032 | { | 3035 | { |
3033 | if ([self readStream] && [self readStreamIsScheduled]) { | 3036 | if ([self readStream] && [self readStreamIsScheduled]) { |
3034 | 3037 | ||
3035 | [connectionsLock lock]; | 3038 | [connectionsLock lock]; |
3036 | runningRequestCount--; | 3039 | runningRequestCount--; |
3037 | - #if TARGET_OS_IPHONE | ||
3038 | if (shouldUpdateNetworkActivityIndicator && runningRequestCount == 0) { | 3040 | if (shouldUpdateNetworkActivityIndicator && runningRequestCount == 0) { |
3039 | - [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; | 3041 | + // Wait half a second before turning off the indicator |
3042 | + // This can prevent flicker when you have a single request finish and then immediately start another request | ||
3043 | + // We will cancel hiding the activity indicator if we start again | ||
3044 | + [[self class] performSelector:@selector(hideNetworkActivityIndicator) withObject:nil afterDelay:0.5]; | ||
3040 | } | 3045 | } |
3041 | - #endif | ||
3042 | [connectionsLock unlock]; | 3046 | [connectionsLock unlock]; |
3043 | 3047 | ||
3044 | [[self readStream] removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:[self runLoopMode]]; | 3048 | [[self readStream] removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:[self runLoopMode]]; |
@@ -3976,14 +3980,27 @@ static NSOperationQueue *sharedQueue = nil; | @@ -3976,14 +3980,27 @@ static NSOperationQueue *sharedQueue = nil; | ||
3976 | [connectionsLock unlock]; | 3980 | [connectionsLock unlock]; |
3977 | return inUse; | 3981 | return inUse; |
3978 | } | 3982 | } |
3979 | -#if TARGET_OS_IPHONE | 3983 | + |
3980 | + (void)setShouldUpdateNetworkActivityIndicator:(BOOL)shouldUpdate | 3984 | + (void)setShouldUpdateNetworkActivityIndicator:(BOOL)shouldUpdate |
3981 | { | 3985 | { |
3982 | [connectionsLock lock]; | 3986 | [connectionsLock lock]; |
3983 | shouldUpdateNetworkActivityIndicator = shouldUpdate; | 3987 | shouldUpdateNetworkActivityIndicator = shouldUpdate; |
3984 | [connectionsLock unlock]; | 3988 | [connectionsLock unlock]; |
3985 | } | 3989 | } |
3990 | + | ||
3991 | ++ (void)showNetworkActivityIndicator | ||
3992 | +{ | ||
3993 | +#if TARGET_OS_IPHONE | ||
3994 | + [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; | ||
3986 | #endif | 3995 | #endif |
3996 | +} | ||
3997 | + | ||
3998 | ++ (void)hideNetworkActivityIndicator | ||
3999 | +{ | ||
4000 | +#if TARGET_OS_IPHONE | ||
4001 | + [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; | ||
4002 | +#endif | ||
4003 | +} | ||
3987 | 4004 | ||
3988 | 4005 | ||
3989 | #pragma mark threading behaviour | 4006 | #pragma mark threading behaviour |
-
Please register or login to post a comment