zoukankan      html  css  js  c++  java
  • 对MBProgressHUD进行二次封装并精简使用

    对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)queue
              completionBlock:(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
    #endif
    
    
    static 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 properties
            self.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 background
            self.opaque = NO;
            self.backgroundColor = [UIColor clearColor];
            // Make it invisible for now
            self.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 display
        if (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 necessary
        if (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 running
        if (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 window
        return 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 in
        if (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 out
        if (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 method
            if (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_AVAILABLE
        if (self.completionBlock) {
            self.completionBlock();
            self.completionBlock = NULL;
        }
    #endif
        if ([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 thread
        self.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)queue
         completionBlock:(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];
    #else
        targetForExecution = 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 view
        UIView *parent = self.superview;
        if (parent) {
            self.frame = parent.bounds;
        }
        CGRect bounds = self.bounds;
        
        // Determine the total width and height needed
        CGFloat 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 elements
        CGFloat 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 rules
        if (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 colours
            size_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 center
            CGPoint gradCenter= CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2);
            //Gradient radius
            float gradRadius = MIN(CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds)) ;
            //Gradient draw
            CGContextDrawRadialGradient (context, gradient, gradCenter,
                                         0, gradCenter, gradRadius,
                                         kCGGradientDrawsAfterEndLocation);
            CGGradientRelease(gradient);
        }
    
        // Set background rect color
        if (self.color) {
            CGContextSetFillColorWithColor(context, self.color.CGColor);
        } else {
            CGContextSetGrayFillColor(context, 0.0f, self.opacity);
        }
    
        
        // Center HUD
        CGRect allRect = self.bounds;
        // Draw rounded HUD backgroud rect
        CGRect 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 superview
        if (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/#214
        CGFloat 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 background
            BOOL 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 degrees
            CGFloat endAngle = (2 * (float)M_PI) + startAngle;
            [processBackgroundPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
            [_backgroundTintColor set];
            [processBackgroundPath stroke];
            // Draw progress
            UIBezierPath *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 progress
            CGPoint center = CGPointMake(CGRectGetWidth(allRect) / 2, CGRectGetHeight(allRect) / 2);
            CGFloat radius = (CGRectGetWidth(allRect) - 4) / 2;
            CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees
            CGFloat 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 background
        float 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 border
        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);
        CGContextStrokePath(context);
        
        CGContextSetFillColorWithColor(context, [_progressColor CGColor]);
        radius = radius - 2;
        float amount = self.progress * CGRectGetWidth(rect);
        
        // Progress in the middle area
        if (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 arc
        else 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 arc
        else 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 *)text
         configParameter:(ConfigShowHUDBlock)config
                duration:(NSTimeInterval)sec
                  inView:(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 *)text
     configParameter:(ConfigShowHUDBlock)config
            duration:(NSTimeInterval)sec
              inView:(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)viewBlock
           configParameter:(ConfigShowHUDBlock)config
                  duration:(NSTimeInterval)sec
                    inView:(UIView *)view;
    
    
    
    
    + (instancetype)showTextOnly:(NSString *)text
                 configParameter:(ConfigShowHUDBlock)config
                          inView:(UIView *)view;
    + (instancetype)showText:(NSString *)text
             configParameter:(ConfigShowHUDBlock)config
                      inView:(UIView *)view;
    + (instancetype)showCustomView:(ConfigShowHUDCustomViewBlock)viewBlock
                   configParameter:(ConfigShowHUDBlock)config
                            inView:(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;
        }
        
        // 自定义view
        if (_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 *)text
         configParameter:(ConfigShowHUDBlock)config
                duration:(NSTimeInterval)sec
                  inView:(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 *)text
     configParameter:(ConfigShowHUDBlock)config
            duration:(NSTimeInterval)sec
              inView:(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)viewBlock
           configParameter:(ConfigShowHUDBlock)config
                  duration:(NSTimeInterval)sec
                    inView:(UIView *)view
    {
        ShowHUD *hud     = [[ShowHUD alloc] initWithView:view];
        hud.margin       = 10.f;
        
        // 配置额外的参数
        config(hud);
        
        // 自定义View
        hud.customView   = viewBlock();
        
        // 显示
        [hud show:YES];
        
        [hud hide:YES afterDelay:sec];
    }
    
    
    + (instancetype)showTextOnly:(NSString *)text
                 configParameter:(ConfigShowHUDBlock)config
                          inView:(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 *)text
             configParameter:(ConfigShowHUDBlock)config
                      inView:(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)viewBlock
                   configParameter:(ConfigShowHUDBlock)config
                            inView:(UIView *)view
    {
        ShowHUD *hud     = [[ShowHUD alloc] initWithView:view];
        hud.margin       = 10.f;
        
        // 配置额外的参数
        config(hud);
        
        // 自定义View
        hud.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:self
                   action:@selector(buttonEvent:)
         forControlEvents:UIControlEventTouchUpInside];
    }
    
    - (void)buttonEvent:(id)sender
    {
        [self showHUD];
    }
    
    @end

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

  • 相关阅读:
    千亿美元规模,云计算的下半场将走向何方?
    巧用云原生能力和工具,提升云上运维效率
    基础设施代码化(IaC)的自动化配置与编排
    盘点2020 | 阿里云弹性计算年度关键词:快、弹、稳
    整体算力提升40% 芯片级安全防护 | 阿里云发布第七代ECS云服务器
    真正云原生的智能运维体系,阿里云发布ECS自动化运维套件
    安装wireshark
    查看linux的登录日志 centos7
    CentOS查看系统当前登录用户信息的4种方法
    free -m查询内存使用情况,祥解
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/4003815.html
Copyright © 2011-2022 走看看