对MBProgressHUD进行二次封装并精简使用

https://github.com/jdg/MBProgressHUD

几个效果图:

以下源码是MBProgressHUD支持最新的iOS8的版本,没有任何的警告信息

MBProgressHUD.h 与 MBProgressHUD.m

//
//  MBProgressHUD.h
//  Version 0.9
//  Created by Matej Bukovinski on 2.4.09.
//// This code is distributed under the terms and conditions of the MIT license. // Copyright (c) 2013 Matej Bukovinski
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <CoreGraphics/CoreGraphics.h>@protocol MBProgressHUDDelegate;typedef enum {/** Progress is shown using an UIActivityIndicatorView. This is the default. */MBProgressHUDModeIndeterminate,/** Progress is shown using a round, pie-chart like, progress view. */MBProgressHUDModeDeterminate,/** Progress is shown using a horizontal progress bar */MBProgressHUDModeDeterminateHorizontalBar,/** Progress is shown using a ring-shaped progress view. */MBProgressHUDModeAnnularDeterminate,/** Shows a custom view */MBProgressHUDModeCustomView,/** Shows only labels */MBProgressHUDModeText
} MBProgressHUDMode;typedef enum {/** Opacity animation */MBProgressHUDAnimationFade,/** Opacity + scale animation */MBProgressHUDAnimationZoom,MBProgressHUDAnimationZoomOut = MBProgressHUDAnimationZoom,MBProgressHUDAnimationZoomIn
} MBProgressHUDAnimation;#ifndef MB_INSTANCETYPE
#if __has_feature(objc_instancetype)#define MB_INSTANCETYPE instancetype
#else#define MB_INSTANCETYPE id
#endif
#endif#ifndef MB_STRONG
#if __has_feature(objc_arc)#define MB_STRONG strong
#else#define MB_STRONG retain
#endif
#endif#ifndef MB_WEAK
#if __has_feature(objc_arc_weak)#define MB_WEAK weak
#elif __has_feature(objc_arc)#define MB_WEAK unsafe_unretained
#else#define MB_WEAK assign
#endif
#endif#if NS_BLOCKS_AVAILABLE
typedef void (^MBProgressHUDCompletionBlock)();
#endif/** * Displays a simple HUD window containing a progress indicator and two optional labels for short messages.** This is a simple drop-in class for displaying a progress HUD view similar to Apple's private UIProgressHUD class.* The MBProgressHUD window spans over the entire space given to it by the initWithFrame constructor and catches all* user input on this region, thereby preventing the user operations on components below the view. The HUD itself is* drawn centered as a rounded semi-transparent view which resizes depending on the user specified content.** This view supports four modes of operation:* - MBProgressHUDModeIndeterminate - shows a UIActivityIndicatorView* - MBProgressHUDModeDeterminate - shows a custom round progress indicator* - MBProgressHUDModeAnnularDeterminate - shows a custom annular progress indicator* - MBProgressHUDModeCustomView - shows an arbitrary, user specified view (@see customView)** All three modes can have optional labels assigned:* - If the labelText property is set and non-empty then a label containing the provided content is placed below the*   indicator view.* - If also the detailsLabelText property is set then another label is placed below the first label.*/
@interface MBProgressHUD : UIView/*** Creates a new HUD, adds it to provided view and shows it. The counterpart to this method is hideHUDForView:animated:.* * @param view The view that the HUD will be added to* @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use* animations while appearing.* @return A reference to the created HUD.** @see hideHUDForView:animated:* @see animationType*/
+ (MB_INSTANCETYPE)showHUDAddedTo:(UIView *)view animated:(BOOL)animated;/*** Finds the top-most HUD subview and hides it. The counterpart to this method is showHUDAddedTo:animated:.** @param view The view that is going to be searched for a HUD subview.* @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use* animations while disappearing.* @return YES if a HUD was found and removed, NO otherwise. ** @see showHUDAddedTo:animated:* @see animationType*/
+ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated;/*** Finds all the HUD subviews and hides them. ** @param view The view that is going to be searched for HUD subviews.* @param animated If set to YES the HUDs will disappear using the current animationType. If set to NO the HUDs will not use* animations while disappearing.* @return the number of HUDs found and removed.** @see hideHUDForView:animated:* @see animationType*/
+ (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated;/*** Finds the top-most HUD subview and returns it. ** @param view The view that is going to be searched.* @return A reference to the last HUD subview discovered.*/
+ (MB_INSTANCETYPE)HUDForView:(UIView *)view;/*** Finds all HUD subviews and returns them.** @param view The view that is going to be searched.* @return All found HUD views (array of MBProgressHUD objects).*/
+ (NSArray *)allHUDsForView:(UIView *)view;/*** A convenience constructor that initializes the HUD with the window's bounds. Calls the designated constructor with* window.bounds as the parameter.** @param window The window instance that will provide the bounds for the HUD. Should be the same instance as* the HUD's superview (i.e., the window that the HUD will be added to).*/
- (id)initWithWindow:(UIWindow *)window;/*** A convenience constructor that initializes the HUD with the view's bounds. Calls the designated constructor with* view.bounds as the parameter** @param view The view instance that will provide the bounds for the HUD. Should be the same instance as* the HUD's superview (i.e., the view that the HUD will be added to).*/
- (id)initWithView:(UIView *)view;/** * Display the HUD. You need to make sure that the main thread completes its run loop soon after this method call so* the user interface can be updated. Call this method when your task is already set-up to be executed in a new thread* (e.g., when using something like NSOperation or calling an asynchronous call like NSURLRequest).** @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use* animations while appearing.** @see animationType*/
- (void)show:(BOOL)animated;/** * Hide the HUD. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to* hide the HUD when your task completes.** @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use* animations while disappearing.** @see animationType*/
- (void)hide:(BOOL)animated;/** * Hide the HUD after a delay. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to* hide the HUD when your task completes.** @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use* animations while disappearing.* @param delay Delay in seconds until the HUD is hidden.** @see animationType*/
- (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay;/** * Shows the HUD while a background task is executing in a new thread, then hides the HUD.** This method also takes care of autorelease pools so your method does not have to be concerned with setting up a* pool.** @param method The method to be executed while the HUD is shown. This method will be executed in a new thread.* @param target The object that the target method belongs to.* @param object An optional object to be passed to the method.* @param animated If set to YES the HUD will (dis)appear using the current animationType. If set to NO the HUD will not use* animations while (dis)appearing.*/
- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated;#if NS_BLOCKS_AVAILABLE/*** Shows the HUD while a block is executing on a background queue, then hides the HUD.** @see showAnimated:whileExecutingBlock:onQueue:completionBlock:*/
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block;/*** Shows the HUD while a block is executing on a background queue, then hides the HUD.** @see showAnimated:whileExecutingBlock:onQueue:completionBlock:*/
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(MBProgressHUDCompletionBlock)completion;/*** Shows the HUD while a block is executing on the specified dispatch queue, then hides the HUD.** @see showAnimated:whileExecutingBlock:onQueue:completionBlock:*/
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue;/** * Shows the HUD while a block is executing on the specified dispatch queue, executes completion block on the main queue, and then hides the HUD.** @param animated If set to YES the HUD will (dis)appear using the current animationType. If set to NO the HUD will* not use animations while (dis)appearing.* @param block The block to be executed while the HUD is shown.* @param queue The dispatch queue on which the block should be executed.* @param completion The block to be executed on completion.** @see completionBlock*/
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queuecompletionBlock:(MBProgressHUDCompletionBlock)completion;/*** A block that gets called after the HUD was completely hidden.*/
@property (copy) MBProgressHUDCompletionBlock completionBlock;#endif/** * MBProgressHUD operation mode. The default is MBProgressHUDModeIndeterminate.** @see MBProgressHUDMode*/
@property (assign) MBProgressHUDMode mode;/*** The animation type that should be used when the HUD is shown and hidden. ** @see MBProgressHUDAnimation*/
@property (assign) MBProgressHUDAnimation animationType;/*** The UIView (e.g., a UIImageView) to be shown when the HUD is in MBProgressHUDModeCustomView.* For best results use a 37 by 37 pixel view (so the bounds match the built in indicator bounds). */
@property (MB_STRONG) UIView *customView;/** * The HUD delegate object. ** @see MBProgressHUDDelegate*/
@property (MB_WEAK) id<MBProgressHUDDelegate> delegate;/** * An optional short message to be displayed below the activity indicator. The HUD is automatically resized to fit* the entire text. If the text is too long it will get clipped by displaying "..." at the end. If left unchanged or* set to @"", then no message is displayed.*/
@property (copy) NSString *labelText;/** * An optional details message displayed below the labelText message. This message is displayed only if the labelText* property is also set and is different from an empty string (@""). The details text can span multiple lines. */
@property (copy) NSString *detailsLabelText;/** * The opacity of the HUD window. Defaults to 0.8 (80% opacity). */
@property (assign) float opacity;/*** The color of the HUD window. Defaults to black. If this property is set, color is set using* this UIColor and the opacity property is not used.  using retain because performing copy on* UIColor base colors (like [UIColor greenColor]) cause problems with the copyZone.*/
@property (MB_STRONG) UIColor *color;/** * The x-axis offset of the HUD relative to the centre of the superview. */
@property (assign) float xOffset;/** * The y-axis offset of the HUD relative to the centre of the superview. */
@property (assign) float yOffset;/*** The amount of space between the HUD edge and the HUD elements (labels, indicators or custom views). * Defaults to 20.0*/
@property (assign) float margin;/*** The corner radius for the HUD* Defaults to 10.0*/
@property (assign) float cornerRadius;/** * Cover the HUD background view with a radial gradient. */
@property (assign) BOOL dimBackground;/** Grace period is the time (in seconds) that the invoked method may be run without * showing the HUD. If the task finishes before the grace time runs out, the HUD will* not be shown at all. * This may be used to prevent HUD display for very short tasks.* Defaults to 0 (no grace time).* Grace time functionality is only supported when the task status is known!* @see taskInProgress*/
@property (assign) float graceTime;/*** The minimum time (in seconds) that the HUD is shown. * This avoids the problem of the HUD being shown and than instantly hidden.* Defaults to 0 (no minimum show time).*/
@property (assign) float minShowTime;/*** Indicates that the executed operation is in progress. Needed for correct graceTime operation.* If you don't set a graceTime (different than 0.0) this does nothing.* This property is automatically set when using showWhileExecuting:onTarget:withObject:animated:.* When threading is done outside of the HUD (i.e., when the show: and hide: methods are used directly),* you need to set this property when your task starts and completes in order to have normal graceTime * functionality.*/
@property (assign) BOOL taskInProgress;/*** Removes the HUD from its parent view when hidden. * Defaults to NO. */
@property (assign) BOOL removeFromSuperViewOnHide;/** * Font to be used for the main label. Set this property if the default is not adequate. */
@property (MB_STRONG) UIFont* labelFont;/*** Color to be used for the main label. Set this property if the default is not adequate.*/
@property (MB_STRONG) UIColor* labelColor;/*** Font to be used for the details label. Set this property if the default is not adequate.*/
@property (MB_STRONG) UIFont* detailsLabelFont;/** * Color to be used for the details label. Set this property if the default is not adequate.*/
@property (MB_STRONG) UIColor* detailsLabelColor;/*** The color of the activity indicator. Defaults to [UIColor whiteColor]* Does nothing on pre iOS 5.*/
@property (MB_STRONG) UIColor *activityIndicatorColor;/** * The progress of the progress indicator, from 0.0 to 1.0. Defaults to 0.0. */
@property (assign) float progress;/*** The minimum size of the HUD bezel. Defaults to CGSizeZero (no minimum size).*/
@property (assign) CGSize minSize;/*** The actual size of the HUD bezel.* You can use this to limit touch handling on the bezel aria only.* @see https://github.com/jdg/MBProgressHUD/pull/200*/
@property (atomic, assign, readonly) CGSize size;/*** Force the HUD dimensions to be equal if possible. */
@property (assign, getter = isSquare) BOOL square;@end@protocol MBProgressHUDDelegate <NSObject>@optional/** * Called after the HUD was fully hidden from the screen. */
- (void)hudWasHidden:(MBProgressHUD *)hud;@end/*** A progress view for showing definite progress by filling up a circle (pie chart).*/
@interface MBRoundProgressView : UIView /*** Progress (0.0 to 1.0)*/
@property (nonatomic, assign) float progress;/*** Indicator progress color.* Defaults to white [UIColor whiteColor]*/
@property (nonatomic, MB_STRONG) UIColor *progressTintColor;/*** Indicator background (non-progress) color.* Defaults to translucent white (alpha 0.1)*/
@property (nonatomic, MB_STRONG) UIColor *backgroundTintColor;/** Display mode - NO = round or YES = annular. Defaults to round.*/
@property (nonatomic, assign, getter = isAnnular) BOOL annular;@end/*** A flat bar progress view. */
@interface MBBarProgressView : UIView/*** Progress (0.0 to 1.0)*/
@property (nonatomic, assign) float progress;/*** Bar border line color.* Defaults to white [UIColor whiteColor].*/
@property (nonatomic, MB_STRONG) UIColor *lineColor;/*** Bar background color.* Defaults to clear [UIColor clearColor];*/
@property (nonatomic, MB_STRONG) UIColor *progressRemainingColor;/*** Bar progress color.* Defaults to white [UIColor whiteColor].*/
@property (nonatomic, MB_STRONG) UIColor *progressColor;@end

MBProgressHUD.h

//
// MBProgressHUD.m
// Version 0.9
// Created by Matej Bukovinski on 2.4.09.
//

#import "MBProgressHUD.h"
#import <tgmath.h>#if __has_feature(objc_arc)#define MB_AUTORELEASE(exp) exp#define MB_RELEASE(exp) exp#define MB_RETAIN(exp) exp
#else#define MB_AUTORELEASE(exp) [exp autorelease]#define MB_RELEASE(exp) [exp release]#define MB_RETAIN(exp) [exp retain]
#endif#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000#define MBLabelAlignmentCenter NSTextAlignmentCenter
#else#define MBLabelAlignmentCenter UITextAlignmentCenter
#endif#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000#define MB_TEXTSIZE(text, font) [text length] > 0 ? [text \sizeWithAttributes:@{NSFontAttributeName:font}] : CGSizeZero;
#else#define MB_TEXTSIZE(text, font) [text length] > 0 ? [text sizeWithFont:font] : CGSizeZero;
#endif#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000#define MB_MULTILINE_TEXTSIZE(text, font, maxSize, mode) [text length] > 0 ? [text \boundingRectWithSize:maxSize options:(NSStringDrawingUsesLineFragmentOrigin) \attributes:@{NSFontAttributeName:font} context:nil].size : CGSizeZero;
#else#define MB_MULTILINE_TEXTSIZE(text, font, maxSize, mode) [text length] > 0 ? [text \sizeWithFont:font constrainedToSize:maxSize lineBreakMode:mode] : CGSizeZero;
#endif#ifndef kCFCoreFoundationVersionNumber_iOS_7_0#define kCFCoreFoundationVersionNumber_iOS_7_0 847.20
#endif#ifndef kCFCoreFoundationVersionNumber_iOS_8_0#define kCFCoreFoundationVersionNumber_iOS_8_0 1129.15
#endifstatic const CGFloat kPadding = 4.f;
static const CGFloat kLabelFontSize = 16.f;
static const CGFloat kDetailsLabelFontSize = 12.f;@interface MBProgressHUD () {BOOL useAnimation;SEL methodForExecution;id targetForExecution;id objectForExecution;UILabel *label;UILabel *detailsLabel;BOOL isFinished;CGAffineTransform rotationTransform;
}@property (atomic, MB_STRONG) UIView *indicator;
@property (atomic, MB_STRONG) NSTimer *graceTimer;
@property (atomic, MB_STRONG) NSTimer *minShowTimer;
@property (atomic, MB_STRONG) NSDate *showStarted;@end@implementation MBProgressHUD#pragma mark - Properties@synthesize animationType;
@synthesize delegate;
@synthesize opacity;
@synthesize color;
@synthesize labelFont;
@synthesize labelColor;
@synthesize detailsLabelFont;
@synthesize detailsLabelColor;
@synthesize indicator;
@synthesize xOffset;
@synthesize yOffset;
@synthesize minSize;
@synthesize square;
@synthesize margin;
@synthesize dimBackground;
@synthesize graceTime;
@synthesize minShowTime;
@synthesize graceTimer;
@synthesize minShowTimer;
@synthesize taskInProgress;
@synthesize removeFromSuperViewOnHide;
@synthesize customView;
@synthesize showStarted;
@synthesize mode;
@synthesize labelText;
@synthesize detailsLabelText;
@synthesize progress;
@synthesize size;
@synthesize activityIndicatorColor;
#if NS_BLOCKS_AVAILABLE
@synthesize completionBlock;
#endif#pragma mark - Class methods+ (MB_INSTANCETYPE)showHUDAddedTo:(UIView *)view animated:(BOOL)animated {MBProgressHUD *hud = [[self alloc] initWithView:view];hud.removeFromSuperViewOnHide = YES;[view addSubview:hud];[hud show:animated];return MB_AUTORELEASE(hud);
}+ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated {MBProgressHUD *hud = [self HUDForView:view];if (hud != nil) {hud.removeFromSuperViewOnHide = YES;[hud hide:animated];return YES;}return NO;
}+ (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated {NSArray *huds = [MBProgressHUD allHUDsForView:view];for (MBProgressHUD *hud in huds) {hud.removeFromSuperViewOnHide = YES;[hud hide:animated];}return [huds count];
}+ (MB_INSTANCETYPE)HUDForView:(UIView *)view {NSEnumerator *subviewsEnum = [view.subviews reverseObjectEnumerator];for (UIView *subview in subviewsEnum) {if ([subview isKindOfClass:self]) {return (MBProgressHUD *)subview;}}return nil;
}+ (NSArray *)allHUDsForView:(UIView *)view {NSMutableArray *huds = [NSMutableArray array];NSArray *subviews = view.subviews;for (UIView *aView in subviews) {if ([aView isKindOfClass:self]) {[huds addObject:aView];}}return [NSArray arrayWithArray:huds];
}#pragma mark - Lifecycle- (id)initWithFrame:(CGRect)frame {self = [super initWithFrame:frame];if (self) {// Set default values for propertiesself.animationType = MBProgressHUDAnimationFade;self.mode = MBProgressHUDModeIndeterminate;self.labelText = nil;self.detailsLabelText = nil;self.opacity = 0.8f;self.color = nil;self.labelFont = [UIFont boldSystemFontOfSize:kLabelFontSize];self.labelColor = [UIColor whiteColor];self.detailsLabelFont = [UIFont boldSystemFontOfSize:kDetailsLabelFontSize];self.detailsLabelColor = [UIColor whiteColor];self.activityIndicatorColor = [UIColor whiteColor];self.xOffset = 0.0f;self.yOffset = 0.0f;self.dimBackground = NO;self.margin = 20.0f;self.cornerRadius = 10.0f;self.graceTime = 0.0f;self.minShowTime = 0.0f;self.removeFromSuperViewOnHide = NO;self.minSize = CGSizeZero;self.square = NO;self.contentMode = UIViewContentModeCenter;self.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin| UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;// Transparent backgroundself.opaque = NO;self.backgroundColor = [UIColor clearColor];// Make it invisible for nowself.alpha = 0.0f;taskInProgress = NO;rotationTransform = CGAffineTransformIdentity;[self setupLabels];[self updateIndicators];[self registerForKVO];[self registerForNotifications];}return self;
}- (id)initWithView:(UIView *)view {NSAssert(view, @"View must not be nil.");return [self initWithFrame:view.bounds];
}- (id)initWithWindow:(UIWindow *)window {return [self initWithView:window];
}- (void)dealloc {[self unregisterFromNotifications];[self unregisterFromKVO];
#if !__has_feature(objc_arc)[color release];[indicator release];[label release];[detailsLabel release];[labelText release];[detailsLabelText release];[graceTimer release];[minShowTimer release];[showStarted release];[customView release];[labelFont release];[labelColor release];[detailsLabelFont release];[detailsLabelColor release];
#if NS_BLOCKS_AVAILABLE[completionBlock release];
#endif[super dealloc];
#endif
}#pragma mark - Show & hide- (void)show:(BOOL)animated {useAnimation = animated;// If the grace time is set postpone the HUD displayif (self.graceTime > 0.0) {self.graceTimer = [NSTimer scheduledTimerWithTimeInterval:self.graceTime target:self selector:@selector(handleGraceTimer:) userInfo:nil repeats:NO];} // ... otherwise show the HUD imediately else {[self setNeedsDisplay];[self showUsingAnimation:useAnimation];}
}- (void)hide:(BOOL)animated {useAnimation = animated;// If the minShow time is set, calculate how long the hud was shown,// and pospone the hiding operation if necessaryif (self.minShowTime > 0.0 && showStarted) {NSTimeInterval interv = [[NSDate date] timeIntervalSinceDate:showStarted];if (interv < self.minShowTime) {self.minShowTimer = [NSTimer scheduledTimerWithTimeInterval:(self.minShowTime - interv) target:self selector:@selector(handleMinShowTimer:) userInfo:nil repeats:NO];return;} }// ... otherwise hide the HUD immediately
    [self hideUsingAnimation:useAnimation];
}- (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay {[self performSelector:@selector(hideDelayed:) withObject:[NSNumber numberWithBool:animated] afterDelay:delay];
}- (void)hideDelayed:(NSNumber *)animated {[self hide:[animated boolValue]];
}#pragma mark - Timer callbacks- (void)handleGraceTimer:(NSTimer *)theTimer {// Show the HUD only if the task is still runningif (taskInProgress) {[self setNeedsDisplay];[self showUsingAnimation:useAnimation];}
}- (void)handleMinShowTimer:(NSTimer *)theTimer {[self hideUsingAnimation:useAnimation];
}#pragma mark - View Hierrarchy- (BOOL)shouldPerformOrientationTransform {BOOL isPreiOS8 = NSFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_8_0;// prior to iOS8 code needs to take care of rotation if it is being added to the windowreturn isPreiOS8 && [self.superview isKindOfClass:[UIWindow class]];
}- (void)didMoveToSuperview {if ([self shouldPerformOrientationTransform]) {[self setTransformForCurrentOrientation:NO];}
}#pragma mark - Internal show & hide operations- (void)showUsingAnimation:(BOOL)animated {if (animated && animationType == MBProgressHUDAnimationZoomIn) {self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(0.5f, 0.5f));} else if (animated && animationType == MBProgressHUDAnimationZoomOut) {self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(1.5f, 1.5f));}self.showStarted = [NSDate date];// Fade inif (animated) {[UIView beginAnimations:nil context:NULL];[UIView setAnimationDuration:0.30];self.alpha = 1.0f;if (animationType == MBProgressHUDAnimationZoomIn || animationType == MBProgressHUDAnimationZoomOut) {self.transform = rotationTransform;}[UIView commitAnimations];}else {self.alpha = 1.0f;}
}- (void)hideUsingAnimation:(BOOL)animated {// Fade outif (animated && showStarted) {[UIView beginAnimations:nil context:NULL];[UIView setAnimationDuration:0.30];[UIView setAnimationDelegate:self];[UIView setAnimationDidStopSelector:@selector(animationFinished:finished:context:)];// 0.02 prevents the hud from passing through touches during the animation the hud will get completely hidden// in the done methodif (animationType == MBProgressHUDAnimationZoomIn) {self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(1.5f, 1.5f));} else if (animationType == MBProgressHUDAnimationZoomOut) {self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(0.5f, 0.5f));}self.alpha = 0.02f;[UIView commitAnimations];}else {self.alpha = 0.0f;[self done];}self.showStarted = nil;
}- (void)animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void*)context {[self done];
}- (void)done {[NSObject cancelPreviousPerformRequestsWithTarget:self];isFinished = YES;self.alpha = 0.0f;if (removeFromSuperViewOnHide) {[self removeFromSuperview];}
#if NS_BLOCKS_AVAILABLEif (self.completionBlock) {self.completionBlock();self.completionBlock = NULL;}
#endifif ([delegate respondsToSelector:@selector(hudWasHidden:)]) {[delegate performSelector:@selector(hudWasHidden:) withObject:self];}
}#pragma mark - Threading- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated {methodForExecution = method;targetForExecution = MB_RETAIN(target);objectForExecution = MB_RETAIN(object);    // Launch execution in new threadself.taskInProgress = YES;[NSThread detachNewThreadSelector:@selector(launchExecution) toTarget:self withObject:nil];// Show HUD view
    [self show:animated];
}#if NS_BLOCKS_AVAILABLE- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block {dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);[self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:NULL];
}- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(void (^)())completion {dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);[self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:completion];
}- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue {[self showAnimated:animated whileExecutingBlock:block onQueue:queue    completionBlock:NULL];
}- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queuecompletionBlock:(MBProgressHUDCompletionBlock)completion {self.taskInProgress = YES;self.completionBlock = completion;dispatch_async(queue, ^(void) {block();dispatch_async(dispatch_get_main_queue(), ^(void) {[self cleanUp];});});[self show:animated];
}#endif- (void)launchExecution {@autoreleasepool {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"// Start executing the requested task
        [targetForExecution performSelector:methodForExecution withObject:objectForExecution];
#pragma clang diagnostic pop// Task completed, update view in main thread (note: view operations should// be done only in the main thread)
        [self performSelectorOnMainThread:@selector(cleanUp) withObject:nil waitUntilDone:NO];}
}- (void)cleanUp {taskInProgress = NO;
#if !__has_feature(objc_arc)[targetForExecution release];[objectForExecution release];
#elsetargetForExecution = nil;objectForExecution = nil;
#endif[self hide:useAnimation];
}#pragma mark - UI- (void)setupLabels {label = [[UILabel alloc] initWithFrame:self.bounds];label.adjustsFontSizeToFitWidth = NO;label.textAlignment = MBLabelAlignmentCenter;label.opaque = NO;label.backgroundColor = [UIColor clearColor];label.textColor = self.labelColor;label.font = self.labelFont;label.text = self.labelText;[self addSubview:label];detailsLabel = [[UILabel alloc] initWithFrame:self.bounds];detailsLabel.font = self.detailsLabelFont;detailsLabel.adjustsFontSizeToFitWidth = NO;detailsLabel.textAlignment = MBLabelAlignmentCenter;detailsLabel.opaque = NO;detailsLabel.backgroundColor = [UIColor clearColor];detailsLabel.textColor = self.detailsLabelColor;detailsLabel.numberOfLines = 0;detailsLabel.font = self.detailsLabelFont;detailsLabel.text = self.detailsLabelText;[self addSubview:detailsLabel];
}- (void)updateIndicators {BOOL isActivityIndicator = [indicator isKindOfClass:[UIActivityIndicatorView class]];BOOL isRoundIndicator = [indicator isKindOfClass:[MBRoundProgressView class]];if (mode == MBProgressHUDModeIndeterminate) {if (!isActivityIndicator) {// Update to indeterminate indicator
            [indicator removeFromSuperview];self.indicator = MB_AUTORELEASE([[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]);[(UIActivityIndicatorView *)indicator startAnimating];[self addSubview:indicator];}
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 50000[(UIActivityIndicatorView *)indicator setColor:self.activityIndicatorColor];
#endif}else if (mode == MBProgressHUDModeDeterminateHorizontalBar) {// Update to bar determinate indicator
        [indicator removeFromSuperview];self.indicator = MB_AUTORELEASE([[MBBarProgressView alloc] init]);[self addSubview:indicator];}else if (mode == MBProgressHUDModeDeterminate || mode == MBProgressHUDModeAnnularDeterminate) {if (!isRoundIndicator) {// Update to determinante indicator
            [indicator removeFromSuperview];self.indicator = MB_AUTORELEASE([[MBRoundProgressView alloc] init]);[self addSubview:indicator];}if (mode == MBProgressHUDModeAnnularDeterminate) {[(MBRoundProgressView *)indicator setAnnular:YES];}} else if (mode == MBProgressHUDModeCustomView && customView != indicator) {// Update custom view indicator
        [indicator removeFromSuperview];self.indicator = customView;[self addSubview:indicator];} else if (mode == MBProgressHUDModeText) {[indicator removeFromSuperview];self.indicator = nil;}
}#pragma mark - Layout- (void)layoutSubviews {[super layoutSubviews];// Entirely cover the parent viewUIView *parent = self.superview;if (parent) {self.frame = parent.bounds;}CGRect bounds = self.bounds;// Determine the total width and height neededCGFloat maxWidth = CGRectGetWidth(bounds) - 4 * margin;CGSize totalSize = CGSizeZero;CGRect indicatorF = indicator.bounds;indicatorF.size.width = MIN(CGRectGetWidth(indicatorF), maxWidth);totalSize.width = MAX(totalSize.width, CGRectGetWidth(indicatorF));totalSize.height += CGRectGetHeight(indicatorF);CGSize labelSize = MB_TEXTSIZE(label.text, label.font);labelSize.width = MIN(labelSize.width, maxWidth);totalSize.width = MAX(totalSize.width, labelSize.width);totalSize.height += labelSize.height;if (labelSize.height > 0.f && CGRectGetHeight(indicatorF) > 0.f) {totalSize.height += kPadding;}CGFloat remainingHeight = CGRectGetHeight(bounds) - totalSize.height - kPadding - 4 * margin;CGSize maxSize = CGSizeMake(maxWidth, remainingHeight);CGSize detailsLabelSize = MB_MULTILINE_TEXTSIZE(detailsLabel.text, detailsLabel.font, maxSize, detailsLabel.lineBreakMode);totalSize.width = MAX(totalSize.width, detailsLabelSize.width);totalSize.height += detailsLabelSize.height;if (detailsLabelSize.height > 0.f && (indicatorF.size.height > 0.f || labelSize.height > 0.f)) {totalSize.height += kPadding;}totalSize.width += 2 * margin;totalSize.height += 2 * margin;// Position elementsCGFloat yPos = round(((CGRectGetHeight(bounds) - totalSize.height) / 2)) + margin + yOffset;CGFloat xPos = xOffset;indicatorF.origin.y = yPos;indicatorF.origin.x = round((CGRectGetWidth(bounds) - CGRectGetWidth(indicatorF)) / 2) + xPos;indicator.frame = indicatorF;yPos += CGRectGetHeight(indicatorF);if (labelSize.height > 0.f && CGRectGetHeight(indicatorF) > 0.f) {yPos += kPadding;}CGRect labelF;labelF.origin.y = yPos;labelF.origin.x = round((CGRectGetWidth(bounds) - labelSize.width) / 2) + xPos;labelF.size = labelSize;label.frame = labelF;yPos += labelF.size.height;if (detailsLabelSize.height > 0.f && (CGRectGetHeight(indicatorF) > 0.f || labelSize.height > 0.f)) {yPos += kPadding;}CGRect detailsLabelF;detailsLabelF.origin.y = yPos;detailsLabelF.origin.x = round((CGRectGetWidth(bounds) - detailsLabelSize.width) / 2) + xPos;detailsLabelF.size = detailsLabelSize;detailsLabel.frame = detailsLabelF;// Enforce minsize and quare rulesif (square) {CGFloat max = MAX(totalSize.width, totalSize.height);if (max <= bounds.size.width - 2 * margin) {totalSize.width = max;}if (max <= bounds.size.height - 2 * margin) {totalSize.height = max;}}if (totalSize.width < minSize.width) {totalSize.width = minSize.width;} if (totalSize.height < minSize.height) {totalSize.height = minSize.height;}size = totalSize;
}#pragma mark BG Drawing- (void)drawRect:(CGRect)rect {CGContextRef context = UIGraphicsGetCurrentContext();UIGraphicsPushContext(context);if (self.dimBackground) {//Gradient colourssize_t gradLocationsNum = 2;CGFloat gradLocations[2] = {0.0f, 1.0f};CGFloat gradColors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.75f}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradColors, gradLocations, gradLocationsNum);CGColorSpaceRelease(colorSpace);//Gradient centerCGPoint gradCenter= CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2);//Gradient radiusfloat gradRadius = MIN(CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds)) ;//Gradient draw
        CGContextDrawRadialGradient (context, gradient, gradCenter,0, gradCenter, gradRadius,kCGGradientDrawsAfterEndLocation);CGGradientRelease(gradient);}// Set background rect colorif (self.color) {CGContextSetFillColorWithColor(context, self.color.CGColor);} else {CGContextSetGrayFillColor(context, 0.0f, self.opacity);}// Center HUDCGRect allRect = self.bounds;// Draw rounded HUD backgroud rectCGRect boxRect = CGRectMake(round((CGRectGetWidth(allRect) - size.width) / 2) + self.xOffset,round((CGRectGetHeight(allRect) - size.height) / 2) + self.yOffset, size.width, size.height);float radius = self.cornerRadius;CGContextBeginPath(context);CGContextMoveToPoint(context, CGRectGetMinX(boxRect) + radius, CGRectGetMinY(boxRect));CGContextAddArc(context, CGRectGetMaxX(boxRect) - radius, CGRectGetMinY(boxRect) + radius, radius, 3 * (float)M_PI / 2, 0, 0);CGContextAddArc(context, CGRectGetMaxX(boxRect) - radius, CGRectGetMaxY(boxRect) - radius, radius, 0, (float)M_PI / 2, 0);CGContextAddArc(context, CGRectGetMinX(boxRect) + radius, CGRectGetMaxY(boxRect) - radius, radius, (float)M_PI / 2, (float)M_PI, 0);CGContextAddArc(context, CGRectGetMinX(boxRect) + radius, CGRectGetMinY(boxRect) + radius, radius, (float)M_PI, 3 * (float)M_PI / 2, 0);CGContextClosePath(context);CGContextFillPath(context);UIGraphicsPopContext();
}#pragma mark - KVO- (void)registerForKVO {for (NSString *keyPath in [self observableKeypaths]) {[self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL];}
}- (void)unregisterFromKVO {for (NSString *keyPath in [self observableKeypaths]) {[self removeObserver:self forKeyPath:keyPath];}
}- (NSArray *)observableKeypaths {return [NSArray arrayWithObjects:@"mode", @"customView", @"labelText", @"labelFont", @"labelColor",@"detailsLabelText", @"detailsLabelFont", @"detailsLabelColor", @"progress", @"activityIndicatorColor", nil];
}- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {if (![NSThread isMainThread]) {[self performSelectorOnMainThread:@selector(updateUIForKeypath:) withObject:keyPath waitUntilDone:NO];} else {[self updateUIForKeypath:keyPath];}
}- (void)updateUIForKeypath:(NSString *)keyPath {if ([keyPath isEqualToString:@"mode"] || [keyPath isEqualToString:@"customView"] ||[keyPath isEqualToString:@"activityIndicatorColor"]) {[self updateIndicators];} else if ([keyPath isEqualToString:@"labelText"]) {label.text = self.labelText;} else if ([keyPath isEqualToString:@"labelFont"]) {label.font = self.labelFont;} else if ([keyPath isEqualToString:@"labelColor"]) {label.textColor = self.labelColor;} else if ([keyPath isEqualToString:@"detailsLabelText"]) {detailsLabel.text = self.detailsLabelText;} else if ([keyPath isEqualToString:@"detailsLabelFont"]) {detailsLabel.font = self.detailsLabelFont;} else if ([keyPath isEqualToString:@"detailsLabelColor"]) {detailsLabel.textColor = self.detailsLabelColor;} else if ([keyPath isEqualToString:@"progress"]) {if ([indicator respondsToSelector:@selector(setProgress:)]) {[(id)indicator setValue:@(progress) forKey:@"progress"];}return;}[self setNeedsLayout];[self setNeedsDisplay];
}#pragma mark - Notifications- (void)registerForNotifications {NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];[nc addObserver:self selector:@selector(statusBarOrientationDidChange:)name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
}- (void)unregisterFromNotifications {NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];[nc removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
}- (void)statusBarOrientationDidChange:(NSNotification *)notification {UIView *superview = self.superview;if (!superview) {return;} else if ([self shouldPerformOrientationTransform]) {[self setTransformForCurrentOrientation:YES];} else {self.frame = self.superview.bounds;[self setNeedsDisplay];}
}- (void)setTransformForCurrentOrientation:(BOOL)animated {// Stay in sync with the superviewif (self.superview) {self.bounds = self.superview.bounds;[self setNeedsDisplay];}// Window coordinates differ below iOS8// In iOS8 the UIScreen's bounds now interface-oriented// more see https://developer.apple.com/videos/wwdc/2014/#214CGFloat radians = 0;if (NSFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_8_0) {UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;if (UIInterfaceOrientationIsLandscape(orientation)) {if (orientation == UIInterfaceOrientationLandscapeLeft) {radians = -(CGFloat)M_PI_2;} else {radians = (CGFloat)M_PI_2;}self.bounds = CGRectMake(0, 0, CGRectGetHeight(self.bounds), CGRectGetWidth(self.bounds));} else {if (orientation == UIInterfaceOrientationPortraitUpsideDown) {radians = (CGFloat)M_PI;} else {radians = 0;}}}rotationTransform = CGAffineTransformMakeRotation(radians);if (animated) {[UIView beginAnimations:nil context:nil];[UIView setAnimationDuration:0.3];}[self setTransform:rotationTransform];if (animated) {[UIView commitAnimations];}
}@end@implementation MBRoundProgressView#pragma mark - Lifecycle- (id)init {return [self initWithFrame:CGRectMake(0.f, 0.f, 37.f, 37.f)];
}- (id)initWithFrame:(CGRect)frame {self = [super initWithFrame:frame];if (self) {self.backgroundColor = [UIColor clearColor];self.opaque = NO;_progress = 0.f;_annular = NO;_progressTintColor = [[UIColor alloc] initWithWhite:1.f alpha:1.f];_backgroundTintColor = [[UIColor alloc] initWithWhite:1.f alpha:.1f];[self registerForKVO];}return self;
}- (void)dealloc {[self unregisterFromKVO];
#if !__has_feature(objc_arc)[_progressTintColor release];[_backgroundTintColor release];[super dealloc];
#endif
}#pragma mark - Drawing- (void)drawRect:(CGRect)rect {CGRect allRect = self.bounds;CGRect circleRect = CGRectInset(allRect, 2.0f, 2.0f);CGContextRef context = UIGraphicsGetCurrentContext();if (_annular) {// Draw backgroundBOOL isPreiOS7 = NSFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0;CGFloat lineWidth = isPreiOS7 ? 5.f : 2.f;UIBezierPath *processBackgroundPath = [UIBezierPath bezierPath];processBackgroundPath.lineWidth = lineWidth;processBackgroundPath.lineCapStyle = kCGLineCapButt;CGPoint center = CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2);CGFloat radius = (CGRectGetWidth(self.bounds) - lineWidth)/2;CGFloat startAngle = - ((float)M_PI / 2); // 90 degreesCGFloat endAngle = (2 * (float)M_PI) + startAngle;[processBackgroundPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];[_backgroundTintColor set];[processBackgroundPath stroke];// Draw progressUIBezierPath *processPath = [UIBezierPath bezierPath];processPath.lineCapStyle = isPreiOS7 ? kCGLineCapRound : kCGLineCapSquare;processPath.lineWidth = lineWidth;endAngle = (self.progress * 2 * (float)M_PI) + startAngle;[processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];[_progressTintColor set];[processPath stroke];} else {// Draw background
        [_progressTintColor setStroke];[_backgroundTintColor setFill];CGContextSetLineWidth(context, 2.0f);CGContextFillEllipseInRect(context, circleRect);CGContextStrokeEllipseInRect(context, circleRect);// Draw progressCGPoint center = CGPointMake(CGRectGetWidth(allRect) / 2, CGRectGetHeight(allRect) / 2);CGFloat radius = (CGRectGetWidth(allRect) - 4) / 2;CGFloat startAngle = - ((float)M_PI / 2); // 90 degreesCGFloat endAngle = (self.progress * 2 * (float)M_PI) + startAngle;CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 1.0f); // white
        CGContextMoveToPoint(context, center.x, center.y);CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0);CGContextClosePath(context);CGContextFillPath(context);}
}#pragma mark - KVO- (void)registerForKVO {for (NSString *keyPath in [self observableKeypaths]) {[self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL];}
}- (void)unregisterFromKVO {for (NSString *keyPath in [self observableKeypaths]) {[self removeObserver:self forKeyPath:keyPath];}
}- (NSArray *)observableKeypaths {return [NSArray arrayWithObjects:@"progressTintColor", @"backgroundTintColor", @"progress", @"annular", nil];
}- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {[self setNeedsDisplay];
}@end@implementation MBBarProgressView#pragma mark - Lifecycle- (id)init {return [self initWithFrame:CGRectMake(.0f, .0f, 120.0f, 20.0f)];
}- (id)initWithFrame:(CGRect)frame {self = [super initWithFrame:frame];if (self) {_progress = 0.f;_lineColor = [UIColor whiteColor];_progressColor = [UIColor whiteColor];_progressRemainingColor = [UIColor clearColor];self.backgroundColor = [UIColor clearColor];self.opaque = NO;[self registerForKVO];}return self;
}- (void)dealloc {[self unregisterFromKVO];
#if !__has_feature(objc_arc)[_lineColor release];[_progressColor release];[_progressRemainingColor release];[super dealloc];
#endif
}#pragma mark - Drawing- (void)drawRect:(CGRect)rect {CGContextRef context = UIGraphicsGetCurrentContext();CGContextSetLineWidth(context, 2);CGContextSetStrokeColorWithColor(context,[_lineColor CGColor]);CGContextSetFillColorWithColor(context, [_progressRemainingColor CGColor]);// Draw backgroundfloat radius = (CGRectGetHeight(rect) / 2) - 2;CGContextMoveToPoint(context, 2, CGRectGetHeight(rect)/2);CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius);CGContextAddLineToPoint(context, CGRectGetWidth(rect) - radius - 2, 2);CGContextAddArcToPoint(context, CGRectGetWidth(rect) - 2, 2, CGRectGetWidth(rect) - 2, CGRectGetHeight(rect) / 2, radius);CGContextAddArcToPoint(context, CGRectGetWidth(rect) - 2, CGRectGetHeight(rect) - 2, CGRectGetWidth(rect) - radius - 2, CGRectGetHeight(rect) - 2, radius);CGContextAddLineToPoint(context, radius + 2, CGRectGetHeight(rect) - 2);CGContextAddArcToPoint(context, 2, CGRectGetHeight(rect) - 2, 2, CGRectGetHeight(rect)/2, radius);CGContextFillPath(context);// Draw borderCGContextMoveToPoint(context, 2, CGRectGetHeight(rect)/2);CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius);CGContextAddLineToPoint(context, CGRectGetWidth(rect) - radius - 2, 2);CGContextAddArcToPoint(context, CGRectGetWidth(rect) - 2, 2, CGRectGetWidth(rect) - 2, CGRectGetHeight(rect) / 2, radius);CGContextAddArcToPoint(context, CGRectGetWidth(rect) - 2, CGRectGetHeight(rect) - 2, CGRectGetWidth(rect) - radius - 2, CGRectGetHeight(rect) - 2, radius);CGContextAddLineToPoint(context, radius + 2, CGRectGetHeight(rect) - 2);CGContextAddArcToPoint(context, 2, CGRectGetHeight(rect) - 2, 2, CGRectGetHeight(rect)/2, radius);CGContextStrokePath(context);CGContextSetFillColorWithColor(context, [_progressColor CGColor]);radius = radius - 2;float amount = self.progress * CGRectGetWidth(rect);// Progress in the middle areaif (amount >= radius + 4 && amount <= (CGRectGetWidth(rect) - radius - 4)) {CGContextMoveToPoint(context, 4, CGRectGetHeight(rect)/2);CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);CGContextAddLineToPoint(context, amount, 4);CGContextAddLineToPoint(context, amount, radius + 4);CGContextMoveToPoint(context, 4, CGRectGetHeight(rect)/2);CGContextAddArcToPoint(context, 4, CGRectGetHeight(rect) - 4, radius + 4, CGRectGetHeight(rect) - 4, radius);CGContextAddLineToPoint(context, amount, CGRectGetHeight(rect) - 4);CGContextAddLineToPoint(context, amount, radius + 4);CGContextFillPath(context);}// Progress in the right arcelse if (amount > radius + 4) {float x = amount - (CGRectGetWidth(rect) - radius - 4);CGContextMoveToPoint(context, 4, CGRectGetHeight(rect)/2);CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);CGContextAddLineToPoint(context, CGRectGetWidth(rect) - radius - 4, 4);float angle = -acos(x/radius);if (isnan(angle)) angle = 0;CGContextAddArc(context, CGRectGetWidth(rect) - radius - 4, CGRectGetHeight(rect)/2, radius, M_PI, angle, 0);CGContextAddLineToPoint(context, amount, CGRectGetHeight(rect)/2);CGContextMoveToPoint(context, 4, CGRectGetHeight(rect)/2);CGContextAddArcToPoint(context, 4, CGRectGetHeight(rect) - 4, radius + 4, CGRectGetHeight(rect) - 4, radius);CGContextAddLineToPoint(context, CGRectGetWidth(rect) - radius - 4, CGRectGetHeight(rect) - 4);angle = acos(x/radius);if (isnan(angle)) angle = 0;CGContextAddArc(context, CGRectGetWidth(rect) - radius - 4, CGRectGetHeight(rect)/2, radius, -M_PI, angle, 1);CGContextAddLineToPoint(context, amount, CGRectGetHeight(rect)/2);CGContextFillPath(context);}// Progress is in the left arcelse if (amount < radius + 4 && amount > 0) {CGContextMoveToPoint(context, 4, CGRectGetHeight(rect)/2);CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);CGContextAddLineToPoint(context, radius + 4, CGRectGetHeight(rect)/2);CGContextMoveToPoint(context, 4, CGRectGetHeight(rect)/2);CGContextAddArcToPoint(context, 4, CGRectGetHeight(rect) - 4, radius + 4, CGRectGetHeight(rect) - 4, radius);CGContextAddLineToPoint(context, radius + 4, CGRectGetHeight(rect)/2);CGContextFillPath(context);}
}#pragma mark - KVO- (void)registerForKVO {for (NSString *keyPath in [self observableKeypaths]) {[self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL];}
}- (void)unregisterFromKVO {for (NSString *keyPath in [self observableKeypaths]) {[self removeObserver:self forKeyPath:keyPath];}
}- (NSArray *)observableKeypaths {return [NSArray arrayWithObjects:@"lineColor", @"progressRemainingColor", @"progressColor", @"progress", nil];
}- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {[self setNeedsDisplay];
}@end

MBProgressHUD.m

以下是本人在MBProgressHUD基础上封装的类,觉得部分的使用基于block

ShowHUD.h 与 ShowHUD.m

//
//  ShowHUD.h
//  TestHUD
//
//  Created by YouXianMing on 14-9-29.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "MBProgressHUD.h"
@class ShowHUD;// 定义block
typedef void (^ConfigShowHUDBlock)(ShowHUD *config);
typedef UIView *(^ConfigShowHUDCustomViewBlock)();// 定义枚举值
typedef enum {Fade    = MBProgressHUDAnimationFade,Zoom    = MBProgressHUDAnimationZoom,ZoomOut = MBProgressHUDAnimationZoomOut,ZoomIn  = MBProgressHUDAnimationZoomIn,
} HUDAnimationType;@interface ShowHUD : NSObject// 动画效果
@property (nonatomic, assign) HUDAnimationType   animationStyle;  // 动画样式// 文本加菊花
@property (nonatomic, strong) NSString          *text;            // 文本
@property (nonatomic, strong) UIFont            *textFont;        // 文本字体// 自定义view
@property (nonatomic, strong) UIView            *customView;      // 自定义view  37x37尺寸// 只显示文本的相关设置
@property (nonatomic, assign) BOOL               showTextOnly;    // 只显示文本// 边缘留白
@property (nonatomic, assign) float              margin;          // 边缘留白// 颜色设置(设置了颜色之后,透明度就会失效)
@property (nonatomic, strong) UIColor           *backgroundColor; // 背景颜色
@property (nonatomic, strong) UIColor           *labelColor;      // 文本颜色// 透明度
@property (nonatomic, assign) float              opacity;         // 透明度// 圆角
@property (nonatomic, assign) float              cornerRadius;    // 圆角// 仅仅显示文本并持续几秒的方法
/* - 使用示例 -[ShowHUD showTextOnly:@"请稍后,显示不了..."configParameter:^(ShowHUD *config) {config.margin          = 10.f;    // 边缘留白config.opacity         = 0.7f;    // 设定透明度config.cornerRadius    = 2.f;     // 设定圆角} duration:3 inView:self.view];*/
+ (void)showTextOnly:(NSString *)textconfigParameter:(ConfigShowHUDBlock)configduration:(NSTimeInterval)secinView:(UIView *)view;// 显示文本与菊花并持续几秒的方法(文本为nil时只显示菊花)
/* - 使用示例 -[ShowHUD showText:@"请稍后,显示不了..."configParameter:^(ShowHUD *config) {config.margin          = 10.f;    // 边缘留白config.opacity         = 0.7f;    // 设定透明度config.cornerRadius    = 2.f;     // 设定圆角} duration:3 inView:self.view];*/
+ (void)showText:(NSString *)textconfigParameter:(ConfigShowHUDBlock)configduration:(NSTimeInterval)secinView:(UIView *)view;// 加载自定义view并持续几秒的方法
/* - 使用示例 -[ShowHUD showText:@"请稍后,显示不了..."configParameter:^(ShowHUD *config) {config.margin          = 10.f;    // 边缘留白config.opacity         = 0.7f;    // 设定透明度config.cornerRadius    = 2.f;     // 设定圆角} duration:3 inView:self.view];*/
+ (void)showCustomView:(ConfigShowHUDCustomViewBlock)viewBlockconfigParameter:(ConfigShowHUDBlock)configduration:(NSTimeInterval)secinView:(UIView *)view;+ (instancetype)showTextOnly:(NSString *)textconfigParameter:(ConfigShowHUDBlock)configinView:(UIView *)view;
+ (instancetype)showText:(NSString *)textconfigParameter:(ConfigShowHUDBlock)configinView:(UIView *)view;
+ (instancetype)showCustomView:(ConfigShowHUDCustomViewBlock)viewBlockconfigParameter:(ConfigShowHUDBlock)configinView:(UIView *)view;
- (void)hide;@end

//
//  ShowHUD.m
//  TestHUD
//
//  Created by YouXianMing on 14-9-29.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import "ShowHUD.h"#ifdef DEBUG
#define ShowHUD_DLog(fmt, ...) NSLog((@"ShowHUD.m:%s:%d" fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#define ShowHUD_DLog(...)
#endif@interface ShowHUD ()<MBProgressHUDDelegate>{MBProgressHUD   *_hud;
}@end@implementation ShowHUD- (instancetype)initWithView:(UIView *)view
{if (view == nil) {return nil;}self = [super init];if (self) {_hud = [[MBProgressHUD alloc] initWithView:view];_hud.delegate                  = self;                       // 设置代理_hud.animationType             = MBProgressHUDAnimationZoom; // 默认动画样式_hud.removeFromSuperViewOnHide = YES;                        // 该视图隐藏后则自动从父视图移除掉
        [view addSubview:_hud];}return self;
}- (void)hide:(BOOL)hide afterDelay:(NSTimeInterval)delay
{[_hud hide:hide afterDelay:delay];
}- (void)hide
{[_hud hide:YES];
}- (void)show:(BOOL)show
{// 根据属性判断是否要显示文本if (_text != nil && _text.length != 0) {_hud.labelText = _text;}// 设置文本字体if (_textFont) {_hud.labelFont = _textFont;}// 如果设置这个属性,则只显示文本if (_showTextOnly == YES && _text != nil && _text.length != 0) {_hud.mode = MBProgressHUDModeText;}// 设置背景色if (_backgroundColor) {_hud.color = _backgroundColor;}// 文本颜色if (_labelColor) {_hud.labelColor = _labelColor;}// 设置圆角if (_cornerRadius) {_hud.cornerRadius = _cornerRadius;}// 设置透明度if (_opacity) {_hud.opacity = _opacity;}// 自定义viewif (_customView) {_hud.mode = MBProgressHUDModeCustomView;_hud.customView = _customView;}// 边缘留白if (_margin > 0) {_hud.margin = _margin;}[_hud show:show];
}#pragma mark - HUD代理方法
- (void)hudWasHidden:(MBProgressHUD *)hud
{[_hud removeFromSuperview];_hud = nil;
}#pragma mark - 重写setter方法
@synthesize animationStyle = _animationStyle;
- (void)setAnimationStyle:(HUDAnimationType)animationStyle
{_animationStyle    = animationStyle;_hud.animationType = (MBProgressHUDAnimation)_animationStyle;
}
- (HUDAnimationType)animationStyle
{return _animationStyle;
}#pragma mark - 便利的方法
+ (void)showTextOnly:(NSString *)textconfigParameter:(ConfigShowHUDBlock)configduration:(NSTimeInterval)secinView:(UIView *)view
{ShowHUD *hud     = [[ShowHUD alloc] initWithView:view];hud.text         = text;hud.showTextOnly = YES;hud.margin       = 10.f;// 配置额外的参数
    config(hud);// 显示
    [hud show:YES];// 延迟sec后消失
    [hud hide:YES afterDelay:sec];
}+ (void)showText:(NSString *)textconfigParameter:(ConfigShowHUDBlock)configduration:(NSTimeInterval)secinView:(UIView *)view
{ShowHUD *hud     = [[ShowHUD alloc] initWithView:view];hud.text         = text;hud.margin       = 10.f;// 配置额外的参数
    config(hud);// 显示
    [hud show:YES];// 延迟sec后消失
    [hud hide:YES afterDelay:sec];
}+ (void)showCustomView:(ConfigShowHUDCustomViewBlock)viewBlockconfigParameter:(ConfigShowHUDBlock)configduration:(NSTimeInterval)secinView:(UIView *)view
{ShowHUD *hud     = [[ShowHUD alloc] initWithView:view];hud.margin       = 10.f;// 配置额外的参数
    config(hud);// 自定义Viewhud.customView   = viewBlock();// 显示
    [hud show:YES];[hud hide:YES afterDelay:sec];
}+ (instancetype)showTextOnly:(NSString *)textconfigParameter:(ConfigShowHUDBlock)configinView:(UIView *)view
{ShowHUD *hud     = [[ShowHUD alloc] initWithView:view];hud.text         = text;hud.showTextOnly = YES;hud.margin       = 10.f;// 配置额外的参数
    config(hud);// 显示
    [hud show:YES];return hud;
}+ (instancetype)showText:(NSString *)textconfigParameter:(ConfigShowHUDBlock)configinView:(UIView *)view
{ShowHUD *hud     = [[ShowHUD alloc] initWithView:view];hud.text         = text;hud.margin       = 10.f;// 配置额外的参数
    config(hud);// 显示
    [hud show:YES];return hud;
}+ (instancetype)showCustomView:(ConfigShowHUDCustomViewBlock)viewBlockconfigParameter:(ConfigShowHUDBlock)configinView:(UIView *)view
{ShowHUD *hud     = [[ShowHUD alloc] initWithView:view];hud.margin       = 10.f;// 配置额外的参数
    config(hud);// 自定义Viewhud.customView   = viewBlock();// 显示
    [hud show:YES];return hud;
}- (void)dealloc
{ShowHUD_DLog(@"资源释放了,没有泄露^_^");
}@end

使用时候的源码如下:

//
//  ViewController.m
//  TestHUD
//
//  Created by YouXianMing on 14-9-29.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import "ViewController.h"
#import "ShowHUD.h" // 引入头文件

typedef enum : NSUInteger {CASE_1, // 显示文本和菊花,延时3秒后消失CASE_2, // 仅仅显示文本,延时3秒后消失CASE_3, // 加载自定义view,3秒后消失
} E_CASE;@interface ViewController ()<MBProgressHUDDelegate>@property (nonatomic, assign) NSInteger  caseType;@end@implementation ViewController- (void)showHUD
{UIWindow *window =  [UIApplication sharedApplication].keyWindow;switch (_caseType++ % 3) {case CASE_1: {[ShowHUD showText:@"YouXianMing"configParameter:^(ShowHUD *config) {config.margin          = 10.f;    // 边缘留白config.opacity         = 0.7f;    // 设定透明度config.cornerRadius    = 1.f;     // 设定圆角config.textFont        = [UIFont systemFontOfSize:11.f];} duration:3 inView:window];} break;case CASE_2: {[ShowHUD showTextOnly:@"YouXianMing"configParameter:^(ShowHUD *config) {config.animationStyle  = ZoomOut;  // 设置动画方式config.margin          = 20.f;     // 边缘留白config.opacity         = 0.8f;     // 设定透明度config.cornerRadius    = 0.1f;     // 设定圆角config.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.8];  // 设置背景色config.labelColor      = [[UIColor whiteColor] colorWithAlphaComponent:1.0];// 设置文本颜色} duration:3 inView:window];} break;//        case CASE_3: {
//            BackgroundView *backView = [[BackgroundView alloc] initInView:window];
//            backView.startDuration = 0.25;
//            backView.endDuration   = 0.25;
//            [backView addToView];
//
//            ShowHUD *hud = [ShowHUD showCustomView:^UIView *{
//                // 返回一个自定义view即可,hud会自动根据你返回的view调整空间
//                MulticolorView *showView = [[MulticolorView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
//                showView.lineWidth       = 1.f;
//                showView.sec             = 1.5f;
//                showView.colors          = @[(id)[UIColor cyanColor].CGColor,
//                                             (id)[UIColor yellowColor].CGColor,
//                                             (id)[UIColor cyanColor].CGColor];
//                [showView startAnimation];
//                return showView;
//            } configParameter:^(ShowHUD *config) {
//                config.animationStyle  = Zoom;   // 设定动画方式
//                config.margin          = 10.f;   // 边缘留白
//                config.cornerRadius    = 2.f;    // 边缘圆角
//                config.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.4f];
//            } inView:window];
//
//            // 延迟5秒后消失
//            [GCDQueue executeInMainQueue:^{
//                [hud hide];
//                [backView removeSelf];
//            } afterDelaySecs:5];
//        } break;default:break;}
}- (void)viewDidLoad {[super viewDidLoad];_caseType = 0;UIButton *button = [[UIButton alloc] initWithFrame:self.view.bounds];[self.view addSubview:button];[button addTarget:selfaction:@selector(buttonEvent:)forControlEvents:UIControlEventTouchUpInside];
}- (void)buttonEvent:(id)sender
{[self showHUD];
}@end

以下是使用上的一些小细节

转载于:https://www.cnblogs.com/YouXianMing/p/4003815.html

对MBProgressHUD进行二次封装并精简使用相关推荐

  1. 基于 POI 封装 ExcelUtil 精简的 Excel 导入导出

    由于 poi 本身只是针对于 excel 等office软件的一个工具包,在一些常规的 excel 导入导出时,还需要再做一次精简的封装,简化代码耦合. 一.现状 本人经历过几家公司的代码封装,导入导 ...

  2. win10二次封装解决办法

    win10封装使用EasySysprep4.5 因为采用的母盘是封装好的系统再次封装会出现问题 在准备工作做好后启动EasySysprep首次封装会报错 报错的log在C:\Windows\Syste ...

  3. Glide二次封装库的使用

    更多代码可以查询本人GitHub:欢迎阅读,star点起来.  Glide二次封装库源码 前言 为什么选择Glide? Glide 轻量级 速度快 可以根据所需加载图片的大小自动适配所需分辨率的图 支 ...

  4. 高德地图markevents_GitHub - mingxuWang/Map: 高德地图API二次封装

    Map组件设计文档 组件设计目的 分析当前各业务方向(销售端.商城.数据可视化.TMS)内地图相关应用的地图功能使用情况,封装Map组件供给各业务向进行使用. 将高德地图API进行二次封装,降低地图相 ...

  5. Android 应用程序集成Google 登录及二次封装

    谷歌登录API:  https://developers.google.com/identity/sign-in/android/ 1.注册并且登录google网站 https://accounts. ...

  6. vue全家桶 ---axios的使用和二次封装

    1.前提基础 本文在vue项目搭建的基础上,vue-router路由配置的基础上,对vue项目中axios的使用进行介绍. 2.axios的使用以及拦截器的设置. 安装axios cnpm i axi ...

  7. iOS安全之二次封装AFN并设置请求头/执行HTTPS加强安全

    以前都是直接复制粘贴二次封装好的代码 , 现在都忘了怎么写 . 恰好当前项目要用到请求头 , 在网上学习了一下 , 统一敲了一遍 .自从到了现在公司 , 才发现要学的东西太多了 , 当然 , 有个好的 ...

  8. java二次封装_基于OKhttp+Rxjava2+Retrofit进行二次封装

    概述 基于Retrofit进行二次封装,优雅的初始化设置.基于Okhttp拦截器和基础缓存,封装了无网络和其他所有场景的缓存策略支持,以及频繁调用请求的丢弃策略. 特性 1.基于Retrofit的二次 ...

  9. Android 应用程序集成FaceBook 登录及二次封装

    1.首先在Facebook 开发者平台注册一个账号 https://developers.facebook.com/ 开发者后台  https://developers.facebook.com/ap ...

最新文章

  1. 共享数字经济之光!世界互联网大会重磅发布“30位新生代数字经济人才”
  2. 程序设计第三次作业附加 代码规范
  3. onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接
  4. 设置在VS2005的IDE中迅速打开xaml文件
  5. webpack loader使用
  6. 无人驾驶入门(camera篇)
  7. motion的移植和使用
  8. E - A very hard mathematic problem----(2015 summer training #3)
  9. Sql server 2008 Express 下载
  10. IOS平台车牌识别技术简介
  11. 解决Eclipse保存web.xml卡的问题
  12. 你和你的女神之间,差了一个OpenCV口红色号识别器,android开发环境的搭建步骤
  13. 2022-05-30 无法验证是否已安装所需的Microsoft更新KB2919355
  14. linux中如何安装windows
  15. python中\t \r \s \n \f各种转移字符含义
  16. NTC(负温度)热敏电阻.阻值的计算方式
  17. 通过 Github Actions 部署 Mkdocs 文档
  18. nodejs typeorm oneToManymanyToOne详细用法
  19. 基于matlab的汽车牌照识别研究
  20. Sentinel-2 (哨兵2号) 数据批量下载教程 [python]

热门文章

  1. 自动执行任务_中小企业如何做运维自动化?
  2. vs code快捷键修改为idea快捷键
  3. 虎牙改名字服务器升级维护中,王一博“虎牙直播”被占id,无奈改了名字,新名字却被吐槽...
  4. 【CCCC】L2-008 最长对称子串 (25分),直接枚举遍历
  5. 【NOIP2007】【Luogu1093】奖学金
  6. java一行输入多个数据类型_Java中的3种输入方式实现解析
  7. vwap算法下单_时间加权平均价格算法(TWAP)和成交量平均算法(VWAP)在量化回测的应用...
  8. docker host模式拿到nginx远程ip端口_FastDFS基于Docker安装,免采坑版
  9. 第二章节 ASP.NET 验证控件(二)
  10. java数组子类型_在vhdl中获取数组子类型的范围属性