2015-07-09 16:02:25 z7222946 阅读数 2309

虽然说swift是基于OC的,但是swift和OC还是有很多去别的,今天我们来说一下枚举变量

下面是某个免费短信验证码的验证方法的返回状态

enum SMS_ResponseState
{
    SMS_ResponseStateFail = 0,
    SMS_ResponseStateSuccess=1
};
这是一个正常的OC枚举写法,但是如果你在swift里面调用这个写在OC里面的枚举想进行操作的话,那么对不起,你会收到各种错误提示

比如你不能这样

if verifyState == SMS_ResponseState.Success

会报下面的错误(这个绝不是.Success调用错的愿意)

'SMS_ResponseState.Type' does not have a member named 'Success'
你也不能这样

<span style="font-size:12px;">if verifyState == 1</span>
会报下面的错误

Binary operator '==' cannot be applied to operands of type 'SMS_ResponseState' and 'Int'

但是下面的方法可以进行调用,但是我没有找到下一步进行操作的方法,有人研究出来还望不吝指教

let state = SMS_ResponseState(1)
同时你也不能这样去写

let state1 = SMS_ResponseState(0)
let state2 = SMS_ResponseState(1)
if state1 == state2 {
}

具体为什么会这样,我也不知道原因,如果哪位大神研究出来了,希望能分享一下,最终我的解决方法是只能修改枚举的写法,比如下面的写法

typedef NS_OPTIONS(NSUInteger, SMS_ResponseState){swift
    SMS_ResponseStateFail = 0,
    SMS_ResponseStateSuccess=1
};



2015-09-28 01:17:41 qq_27484549 阅读数 1193

最近在github上看见一篇<<招聘一个靠谱的iOS>>,看了看里面的试题,都是些很基础又很底层的东西,当然现在还再学习中,能从微博@iOS程序犭袁 所提供的答案中学习到很多之前不知道的知识。现在才察觉到,原来自己的所需要学习的还有很多很多,和这些大牛相比,更是渣渣都不是啊!而且出这套题的”孙源” ,就职于百度,而且还是90后,想想自己一个80后,真的很差,好了,不多说这些,从现在努力向前就好了!

其中第一道题就是有枚举(ENUM)规范写法的问题,正巧今天又在枚举上碰上问题,所以就简单总结了下枚举相关的简单东西。

当然,下面的问题,我就只总结关于枚举。

enter image description here

修改完的代码:

修改方法有很多种,现给出一种做示例:

// .h文件
// 修改完的代码,这是第一种修改方法,后面会给出第二种修改方法

    typedef NS_ENUM(NSInteger, CYLSex) {
        CYLSexMan,
        CYLSexWoman
    };

    @interface CYLUser : NSObject<NSCopying>

    @property (nonatomic, readonly, copy) NSString *name;
    @property (nonatomic, readonly, assign) NSUInteger age;
    @property (nonatomic, readonly, assign) CYLSex sex;

    - (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex;
    + (instancetype)userWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex;

    @end

enum建议使用 NS_ENUMNS_OPTIONS 宏来定义枚举类型,参见官方的 Adopting Modern Objective-C 一文:

// 定义性别的枚举 这样可能就比较严谨
typedef NS_ENUM(NSInteger, CYLUserGender) {
    CYLUserGenderUnknown,
    CYLUserGenderMale,
    CYLUserGenderFemale,
    CYLUserGenderNeuter
};

提供问题答案大神微博 http://weibo.com/luohanchenyilong/
提供问题答案大神的github https://github.com/ChenYilong

  • 常见枚举类型定义
typedef enum
{
    East,
    South,
    West,
    North
}Direction;
  • 在iOS6和Mac OS 10.8以后Apple引入了两个宏来重新定义这两个枚举类型,实际上是将enum定义和typedef合二为一,并且采用不同的宏来从代码角度来区分。
  • 从枚举定义来看,NS_ENUM和NS_OPTIONS本质是一样的,仅仅从字面上来区分其用途。NS_ENUM是通用情况,NS_OPTIONS一般用来定义具有位移操作或特点的情况(bitmask)。
typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {  
        UIViewAnimationTransitionNone,//默认从0开始  
        UIViewAnimationTransitionFlipFromLeft,  
        UIViewAnimationTransitionFlipFromRight,  
        UIViewAnimationTransitionCurlUp,  
        UIViewAnimationTransitionCurlDown,  
    };  

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {  
        UIViewAutoresizingNone                 = 0,  
        UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,  
        UIViewAutoresizingFlexibleWidth        = 1 << 1,  
        UIViewAutoresizingFlexibleRightMargin  = 1 << 2,  
        UIViewAutoresizingFlexibleTopMargin    = 1 << 3,  
        UIViewAutoresizingFlexibleHeight       = 1 << 4,  
        UIViewAutoresizingFlexibleBottomMargin = 1 << 5  
    }; 

这两个宏的定义在Foundation.framework的NSObjCRuntime.h中

#if (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum))  
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type  
#if (__cplusplus)  
#define NS_OPTIONS(_type, _name) _type _name; enum : _type  
#else  
#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type  
#endif  
#else  
#define NS_ENUM(_type, _name) _type _name; enum  
#define NS_OPTIONS(_type, _name) _type _name; enum  
#endif  

Swift中的枚举相对于C语言变化还是很大的

写到这里发觉自己的功底还是不行,然后又去看了大牛的几篇文章,感觉自己再怎么总结,也没有人家的深度与广度,还不如趁这个时间去多学习学习呢!

// Swift 中简单使用枚举 
enum RequsetMethod: String {
    case GET = "GET"
    case POST = "POST"
}

Swift中枚举的使用,这个不算转载吧!参考此篇文章学习吧!

C中枚举使用,这篇博文我感觉就很详细了!参考此篇博文学习吧!

2017-04-28 16:52:53 walkerwqp 阅读数 657

MBProgressHUD.h

#import <Foundation/Foundation.h>

#import "MBProgressHUD.h"


#define SNS_DEPRECATED_ATTRIBUTE __attribute__((deprecated))


typedef enum _tagShowType{

    

    EST_NORMAL=0,

    EST_SUCCESS,

    EST_FAIL,

    

}enShowType;


@interface HudMessageView : NSObject{

    

    MBProgressHUD*  _hud;

    

}


+(HudMessageView*) sharedHudMessageView;

+(void) destroyHudMessageView;


-(id) init;



/////////////////////////////////////////////////////////////////////////

//                                                                     //

//                      新接口,每个接口都可以单独调用                       //

//                                                                     //

/////////////////////////////////////////////////////////////////////////


/*  loading提示

 title       :   提示的文字

 imagePath   :   提示的图片路径,可以为nil,如果是nil则使用默认的菊花图案

 missTime    :   停留的时间,如果是0,则不会自动消失

 */

-(void) loadingPromptWithTitle:(NSString *)title imagePath:(NSString *) imagePath missTime:(float)missTime;


/*  成功提示

 title           :   提示的文字

 succImagePath   :   提示图片,nil的情况默认是对勾图片

 missTime        :   停留时间

 */

-(void) successPromptWithTitle:(NSString *)title succImagePath:(NSString*)succImagePath missTime:(float)missTime;


/*  失败提示

 title           :   提示的文字

 failImagePath   :   提示图片,nil的情况默认是叉叉图片

 missTime        :   停留时间

 */

-(void) failPromptWithTitle:(NSString *)title failImagePath:(NSString*)failImagePath missTime:(float)missTime;


/*  纯文字提示

 title       :   提示的文字

 missTime    :   停留时间,如果是0,则不会自动消失

 */

-(void) wordPromptWithTitle:(NSString *)title missTime:(float) missTime;




/////////////////////////////////////////////////////////////////////////

//                                                                     //

//          以下的接口都是以前的老接口,还可以用,不建议再使用                   //

//                                                                     //

/////////////////////////////////////////////////////////////////////////


//下面的函数

//函数成单调用 调用时设置延时时间 到时间后自动消失

-(void) showWithType:(enShowType)showType title:(NSString*)title afterDelay:(float)afterDelaySNS_DEPRECATED_ATTRIBUTE;

-(void) showWithType:(enShowType)showType title:(NSString*)title afterDelay:(float)afterDelay hudMode:(MBProgressHUDMode)modeSNS_DEPRECATED_ATTRIBUTE;


//下面的函数是过程式 调用方式成对出现

//1. 首先调用showloading 显示状态

//2. 再调用showSuccess 或者 showFailStatus 延时隐藏

-(void) showLoading:(NSString*)titleSNS_DEPRECATED_ATTRIBUTE;

-(void) showSuccessStatus:(NSString*)title afterDelay:(float)afterDelaySNS_DEPRECATED_ATTRIBUTE;

-(void) showSuccessStatusKeepMode:(NSString*)title afterDelay:(float)afterDelaySNS_DEPRECATED_ATTRIBUTE;

-(void) showFailStatus:(NSString*)title afterDelay:(float)afterDelaySNS_DEPRECATED_ATTRIBUTE;

-(void) showFailStatusKeepMode:(NSString*)title afterDelay:(float)afterDelaySNS_DEPRECATED_ATTRIBUTE;

-(void) showLoading:(NSString*)title imagePath:(NSString*)imagePathSNS_DEPRECATED_ATTRIBUTE;

-(void) showSuccessStatus:(NSString*)title succImagePath:(NSString*)succImagePath afterDelay:(float)afterDelaySNS_DEPRECATED_ATTRIBUTE;

-(void) showFailStatus:(NSString*)title failImagPath:(NSString*)failImagPath afterDelay:(float)afterDelaySNS_DEPRECATED_ATTRIBUTE;


-(void) adjustHUDOrientation;


@end


HudMessageView.m

#import "HudMessageView.h"



@implementation HudMessageView


static HudMessageView* g_HudMessageView =nil;

+(HudMessageView*) sharedHudMessageView{

    

    if (nil==g_HudMessageView)

    {

        g_HudMessageView = [[HudMessageViewalloc] init];

    }

    

    returng_HudMessageView;

}


+(void) destroyHudMessageView{

    

    if (g_HudMessageView)

    {

        [g_HudMessageViewrelease];

        g_HudMessageView =nil;

    }

}


-(id) init{

    

    if( (self=[superinit]) ) {

        

        UIWindow *window = [UIApplicationsharedApplication].keyWindow;

        _hud = [[MBProgressHUDalloc] initWithView:window];

        [window addSubview:_hud];

        

        // Set determinate mode

        //_hud.delegate = self;

        _hud.dimBackground =YES;

}

returnself;

}


-(void) dealloc{

    

    [_hudremoveFromSuperview];

    [_hudrelease];

    

    [superdealloc];

}


-(void) showWithType:(enShowType)showType title:(NSString*)title afterDelay:(float)afterDelay{

    

    [selfshowLoading:title];

    

    switch (showType)

    {

        caseEST_NORMAL:

            [_hudhide:YESafterDelay:afterDelay];

            break;

            

        caseEST_SUCCESS:

            [selfshowSuccessStatus:title afterDelay:afterDelay];

            break;

            

        caseEST_FAIL:

            [selfshowFailStatus:title afterDelay:afterDelay];

            break;

            

        default:

            break;

    }

    

}


-(void) showWithType:(enShowType)showType title:(NSString*)title afterDelay:(float)afterDelay hudMode:(MBProgressHUDMode)mode{

    

    [selfshowLoading:title];

    switch (showType)

    {

        caseEST_NORMAL:

            [_hudhide:YESafterDelay:afterDelay];

            break;

            

        caseEST_SUCCESS:

            [selfshowSuccessStatus:title afterDelay:afterDelay];

            break;

            

        caseEST_FAIL:

            [selfshowFailStatus:title afterDelay:afterDelay];

            break;

            

        default:

            break;

    }

    

    _hud.mode = mode;

    

}


-(void) showLoading:(NSString *)title{

    [selfshowLoading:title imagePath:nil];

}


-(void) showLoading:(NSString*)title imagePath:(NSString*)imagePath{

    

    if (imagePath)

    {

        _hud.customView = [[[UIImageViewalloc] initWithImage:[UIImageimageNamed:imagePath]] autorelease];

        _hud.mode =MBProgressHUDModeCustomView;

    }

    else

    {

        _hud.mode =MBProgressHUDModeIndeterminate;

    }

    

    _hud.labelText = title;

    

    [_hudshow:YES];

}


-(void) showSuccessStatus:(NSString *)title afterDelay:(float)afterDelay{

    [selfshowSuccessStatus:title succImagePath:@"055_success@2x.png"afterDelay:afterDelay];

}


-(void) showSuccessStatusKeepMode:(NSString *)title afterDelay:(float)afterDelay{

    [selfshowSuccessStatus:title succImagePath:nilafterDelay:afterDelay];

}


-(void) showSuccessStatus:(NSString*)title succImagePath:(NSString*)succImagePath afterDelay:(float)afterDelay{

    

    if (succImagePath)

    {

        _hud.customView = [[[UIImageViewalloc] initWithImage:[UIImageimageNamed:succImagePath]]autorelease];

        _hud.mode =MBProgressHUDModeCustomView;

    }

    

    _hud.labelText = title;

    

    if (fabs(afterDelay) <0.000001f)

    {

        [_hudhide:YES];

    }

    else

    {

        [_hudhide:YESafterDelay:afterDelay];

    }

}


-(void) showFailStatus:(NSString *)title afterDelay:(float)afterDelay{

    [selfshowFailStatus:title failImagPath:@"055_fail@2x.png"afterDelay:afterDelay];

    

}


-(void) showFailStatusKeepMode:(NSString *)title afterDelay:(float)afterDelay{

    [selfshowFailStatus:title failImagPath:nilafterDelay:afterDelay];

    

}


-(void) showFailStatus:(NSString*)title failImagPath:(NSString*)failImagPath afterDelay:(float)afterDelay{

    

    if (failImagPath)

    {

        _hud.customView = [[[UIImageViewalloc] initWithImage:[UIImage imageNamed_New:failImagPath]]autorelease];

        _hud.mode =MBProgressHUDModeCustomView;

    }

    

    _hud.labelText = title;

    

    if (fabs(afterDelay) <0.000001f)

    {

        [_hudhide:YES];

    }

    else

    {

        [_hudhide:YESafterDelay:afterDelay];

    }

}


-(void) adjustHUDOrientation

{

    [_hud setTransformForCurrentOrientation:NO];

}


-(void) loadingPromptWithTitle:(NSString *)title imagePath:(NSString *) imagePath missTime:(float)missTime

{

    if (imagePath)

    {

        _hud.customView = [[[UIImageViewalloc] initWithImage:[UIImageimageNamed:imagePath]] autorelease];

        _hud.mode =MBProgressHUDModeCustomView;

    }

    else

    {

        _hud.mode =MBProgressHUDModeIndeterminate;

    }

    

    _hud.labelText = title;

    

    if (_hud.dimBackground)

    {

        [_hudshow:YES];

    }

    

    if (fabs(missTime) >0.000001f)

    {

        [_hudhide:YESafterDelay:missTime];

    }

}


-(void) successPromptWithTitle:(NSString *)title succImagePath:(NSString *)succImagePath missTime:(float)missTime

{

    if (_hud.dimBackground)

    {

        if (succImagePath)

        {

            [selfloadingPromptWithTitle:titleimagePath:succImagePath missTime:0];

        }

        else

        {

            [selfloadingPromptWithTitle:titleimagePath:@"055_success"missTime:0];

        }

    }

    else

    {

        if (succImagePath)

        {

            _hud.customView = [[[UIImageViewalloc] initWithImage:[UIImageimageNamed:succImagePath]]autorelease];

        }

        else

        {

            _hud.customView = [[[UIImageViewalloc] initWithImage:[UIImageimageNamed:@"055_success"]]autorelease];

        }

        _hud.mode =MBProgressHUDModeCustomView;

        _hud.labelText = title;

    }

    

    if (fabs(missTime) <0.000001f)

    {

        [_hudhide:YES];

    }

    else

    {

        [_hudhide:YESafterDelay:missTime];

    }

}


-(void) failPromptWithTitle:(NSString *)title failImagePath:(NSString*)failImagePath missTime:(float)missTime

{

    if (_hud.dimBackground)

    {

        if (failImagePath)

        {

            [selfloadingPromptWithTitle:titleimagePath:failImagePath missTime:0];

        }

        else

        {

            [selfloadingPromptWithTitle:titleimagePath:@"055_fail.png"missTime:0];

        }

    }

    else

    {

        if (failImagePath)

        {

            _hud.customView = [[[UIImageViewalloc] initWithImage:[UIImageimageNamed:failImagePath]]autorelease];

        }

        else

        {

            _hud.customView = [[[UIImageViewalloc] initWithImage:[UIImageimageNamed:@"055_fail.png"]]autorelease];

        }

        _hud.mode =MBProgressHUDModeCustomView;

        _hud.labelText = title;

    }

    

    if (fabs(missTime) <0.000001f)

    {

        [_hudhide:YES];

    }

    else

    {

        [_hudhide:YESafterDelay:missTime];

    }

}


-(void) wordPromptWithTitle:(NSString *)title missTime:(float) missTime

{

    _hud.mode =MBProgressHUDModeText;

    _hud.labelText = title;

    if (_hud.dimBackground)

    {

        [_hudshow:YES];

    }

    

    if (fabs(missTime) >0.000001f)

    {

        [_hudhide:YESafterDelay:missTime];

    }

}


@end


MBProgressHUD.h

#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.m

#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 constCGFloat kPadding = 4.f;

static constCGFloat kLabelFontSize =16.f;

static constCGFloat 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 = [[selfalloc] initWithView:view];

    hud.removeFromSuperViewOnHide =YES;

    [view addSubview:hud];

    [hud show:animated];

    returnMB_AUTORELEASE(hud);

}


+ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated {

    MBProgressHUD *hud = [selfHUDForView:view];

    if (hud !=nil) {

        hud.removeFromSuperViewOnHide =YES;

        [hud hide:animated];

        returnYES;

    }

    returnNO;

}


+ (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated {

    NSArray *huds = [MBProgressHUDallHUDsForView:view];

    for (MBProgressHUD *hudin huds) {

        hud.removeFromSuperViewOnHide =YES;

        [hud hide:animated];

    }

    return [hudscount];

}


+ (MB_INSTANCETYPE)HUDForView:(UIView *)view {

    NSEnumerator *subviewsEnum = [view.subviewsreverseObjectEnumerator];

    for (UIView *subviewin subviewsEnum) {

        if ([subviewisKindOfClass:self]) {

            return (MBProgressHUD *)subview;

        }

    }

    returnnil;

}


+ (NSArray *)allHUDsForView:(UIView *)view {

    NSMutableArray *huds = [NSMutableArrayarray];

    NSArray *subviews = view.subviews;

    for (UIView *aViewin subviews) {

        if ([aViewisKindOfClass:self]) {

            [huds addObject:aView];

        }

    }

    return [NSArrayarrayWithArray:huds];

}


#pragma mark - Lifecycle


- (id)initWithFrame:(CGRect)frame {

    self = [superinitWithFrame: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 = [UIFontboldSystemFontOfSize:kLabelFontSize];

        self.labelColor = [UIColorwhiteColor];

        self.detailsLabelFont = [UIFontboldSystemFontOfSize:kDetailsLabelFontSize];

        self.detailsLabelColor = [UIColorwhiteColor];

        self.activityIndicatorColor = [UIColorwhiteColor];

        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 = [UIColorclearColor];

        // Make it invisible for now

        self.alpha =0.0f;

        

        taskInProgress =NO;

        rotationTransform =CGAffineTransformIdentity;

        

        [selfsetupLabels];

        [selfupdateIndicators];

        [selfregisterForKVO];

        [selfregisterForNotifications];

    }

    returnself;

}


- (id)initWithView:(UIView *)view {

    NSAssert(view,@"View must not be nil.");

    return [selfinitWithFrame:view.bounds];

}


- (id)initWithWindow:(UIWindow *)window {

    return [selfinitWithView:window];

}


- (void)dealloc {

    [selfunregisterFromNotifications];

    [selfunregisterFromKVO];

#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 = [NSTimerscheduledTimerWithTimeInterval:self.graceTimetarget:self

                                                         selector:@selector(handleGraceTimer:)userInfo:nilrepeats:NO];

    }

    // ... otherwise show the HUD imediately

    else {

        [selfsetNeedsDisplay];

        [selfshowUsingAnimation: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 = [[NSDatedate] timeIntervalSinceDate:showStarted];

        if (interv <self.minShowTime) {

            self.minShowTimer = [NSTimerscheduledTimerWithTimeInterval:(self.minShowTime - interv)target:self

                                                               selector:@selector(handleMinShowTimer:)userInfo:nilrepeats:NO];

            return;

        }

    }

    // ... otherwise hide the HUD immediately

    [selfhideUsingAnimation:useAnimation];

}


- (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay {

    [selfperformSelector:@selector(hideDelayed:)withObject:[NSNumbernumberWithBool:animated]afterDelay:delay];

}


- (void)hideDelayed:(NSNumber *)animated {

    [selfhide:[animated boolValue]];

}


#pragma mark - Timer callbacks


- (void)handleGraceTimer:(NSTimer *)theTimer {

    // Show the HUD only if the task is still running

    if (taskInProgress) {

        [selfsetNeedsDisplay];

        [selfshowUsingAnimation:useAnimation];

    }

}


- (void)handleMinShowTimer:(NSTimer *)theTimer {

    [selfhideUsingAnimation: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.superviewisKindOfClass:[UIWindowclass]];

}


- (void)didMoveToSuperview {

    if ([selfshouldPerformOrientationTransform]) {

        [selfsetTransformForCurrentOrientation:NO];

    }

}


#pragma mark - Internal show & hide operations


- (void)showUsingAnimation:(BOOL)animated {

    if (animated &&animationType ==MBProgressHUDAnimationZoomIn) {

        self.transform =CGAffineTransformConcat(rotationTransform,CGAffineTransformMakeScale(0.5f,0.5f));

    } elseif (animated &&animationType ==MBProgressHUDAnimationZoomOut) {

        self.transform =CGAffineTransformConcat(rotationTransform,CGAffineTransformMakeScale(1.5f,1.5f));

    }

    self.showStarted = [NSDatedate];

    // Fade in

    if (animated) {

        [UIViewbeginAnimations:nilcontext:NULL];

        [UIViewsetAnimationDuration:0.30];

        self.alpha =1.0f;

        if (animationType ==MBProgressHUDAnimationZoomIn ||animationType ==MBProgressHUDAnimationZoomOut) {

            self.transform =rotationTransform;

        }

        [UIViewcommitAnimations];

    }

    else {

        self.alpha =1.0f;

    }

}


- (void)hideUsingAnimation:(BOOL)animated {

    // Fade out

    if (animated &&showStarted) {

        [UIViewbeginAnimations:nilcontext:NULL];

        [UIViewsetAnimationDuration:0.30];

        [UIViewsetAnimationDelegate:self];

        [UIViewsetAnimationDidStopSelector:@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));

        } elseif (animationType ==MBProgressHUDAnimationZoomOut) {

            self.transform =CGAffineTransformConcat(rotationTransform,CGAffineTransformMakeScale(0.5f,0.5f));

        }

        

        self.alpha =0.02f;

        [UIViewcommitAnimations];

    }

    else {

        self.alpha =0.0f;

        [selfdone];

    }

    self.showStarted =nil;

}


- (void)animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void*)context {

    [selfdone];

}


- (void)done {

    [NSObjectcancelPreviousPerformRequestsWithTarget:self];

    isFinished =YES;

    self.alpha =0.0f;

    if (removeFromSuperViewOnHide) {

        [selfremoveFromSuperview];

    }

#if NS_BLOCKS_AVAILABLE

    if (self.completionBlock) {

        self.completionBlock();

        self.completionBlock =NULL;

    }

#endif

    if ([delegaterespondsToSelector:@selector(hudWasHidden:)]) {

        [delegateperformSelector:@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;

    [NSThreaddetachNewThreadSelector:@selector(launchExecution)toTarget:selfwithObject:nil];

    // Show HUD view

    [selfshow: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);

    [selfshowAnimated: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);

    [selfshowAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:completion];

}


- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue {

    [selfshowAnimated:animated whileExecutingBlock:block onQueue:queuecompletionBlock: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) {

            [selfcleanUp];

        });

    });

    [selfshow:animated];

}


#endif


- (void)launchExecution {

    @autoreleasepool {

#pragma clang diagnostic push

#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

        // Start executing the requested task

        [targetForExecutionperformSelector:methodForExecutionwithObject:objectForExecution];

#pragma clang diagnostic pop

        // Task completed, update view in main thread (note: view operations should

        // be done only in the main thread)

        [selfperformSelectorOnMainThread:@selector(cleanUp)withObject:nilwaitUntilDone:NO];

    }

}


- (void)cleanUp {

    taskInProgress =NO;

#if !__has_feature(objc_arc)

    [targetForExecution release];

    [objectForExecution release];

#else

    targetForExecution =nil;

    objectForExecution =nil;

#endif

    [selfhide:useAnimation];

}


#pragma mark - UI


- (void)setupLabels {

    label = [[UILabelalloc] initWithFrame:self.bounds];

    label.adjustsFontSizeToFitWidth =NO;

    label.textAlignment =MBLabelAlignmentCenter;

    label.opaque =NO;

    label.backgroundColor = [UIColorclearColor];

    label.textColor =self.labelColor;

    label.font =self.labelFont;

    label.text =self.labelText;

    [selfaddSubview:label];

    

    detailsLabel = [[UILabelalloc] initWithFrame:self.bounds];

    detailsLabel.font =self.detailsLabelFont;

    detailsLabel.adjustsFontSizeToFitWidth =NO;

    detailsLabel.textAlignment =MBLabelAlignmentCenter;

    detailsLabel.opaque =NO;

    detailsLabel.backgroundColor = [UIColorclearColor];

    detailsLabel.textColor =self.detailsLabelColor;

    detailsLabel.numberOfLines =0;

    detailsLabel.font =self.detailsLabelFont;

    detailsLabel.text =self.detailsLabelText;

    [selfaddSubview:detailsLabel];

}


- (void)updateIndicators {

    

    BOOL isActivityIndicator = [indicatorisKindOfClass:[UIActivityIndicatorViewclass]];

    BOOL isRoundIndicator = [indicatorisKindOfClass:[MBRoundProgressViewclass]];

    

    if (mode ==MBProgressHUDModeIndeterminate) {

        if (!isActivityIndicator) {

            // Update to indeterminate indicator

            [indicatorremoveFromSuperview];

            self.indicator =MB_AUTORELEASE([[UIActivityIndicatorViewalloc]

                                             initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]);

            [(UIActivityIndicatorView *)indicatorstartAnimating];

            [selfaddSubview:indicator];

        }

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 50000

        [(UIActivityIndicatorView *)indicatorsetColor:self.activityIndicatorColor];

#endif

    }

    elseif (mode ==MBProgressHUDModeDeterminateHorizontalBar) {

        // Update to bar determinate indicator

        [indicatorremoveFromSuperview];

        self.indicator =MB_AUTORELEASE([[MBBarProgressViewalloc] init]);

        [selfaddSubview:indicator];

    }

    elseif (mode ==MBProgressHUDModeDeterminate ||mode == MBProgressHUDModeAnnularDeterminate) {

        if (!isRoundIndicator) {

            // Update to determinante indicator

            [indicatorremoveFromSuperview];

            self.indicator =MB_AUTORELEASE([[MBRoundProgressViewalloc] init]);

            [selfaddSubview:indicator];

        }

        if (mode ==MBProgressHUDModeAnnularDeterminate) {

            [(MBRoundProgressView *)indicatorsetAnnular:YES];

        }

    }

    elseif (mode ==MBProgressHUDModeCustomView &&customView !=indicator) {

        // Update custom view indicator

        [indicatorremoveFromSuperview];

        self.indicator =customView;

        [selfaddSubview:indicator];

    } elseif (mode ==MBProgressHUDModeText) {

        [indicatorremoveFromSuperview];

        self.indicator =nil;

    }

}


#pragma mark - Layout


- (void)layoutSubviews {

    [superlayoutSubviews];

    

    // Entirely cover the parent view

    UIView *parent =self.superview;

    if (parent) {

        

//        if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1)

//        {

//            self.frame = CGRectMake(0.f, 0.f, parent.bounds.size.height, parent.bounds.size.width);

//        }

//        else

        {

            self.frame = parent.bounds;

        }

    }

    CGRect bounds =self.bounds;

    

    // Determine the total widt and height needed

    CGFloat maxWidth = bounds.size.width -4 * margin;

    CGSize totalSize =CGSizeZero;

    

    CGRect indicatorF =indicator.bounds;

    indicatorF.size.width =MIN(indicatorF.size.width, maxWidth);

    totalSize.width =MAX(totalSize.width, indicatorF.size.width);

    totalSize.height += indicatorF.size.height;

    

    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 && indicatorF.size.height >0.f) {

        totalSize.height +=kPadding;

    }

    

    CGFloat remainingHeight = bounds.size.height - 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(((bounds.size.height - totalSize.height) / 2)) + margin +yOffset;

    CGFloat xPos =xOffset;

    indicatorF.origin.y = yPos;

    indicatorF.origin.x =round((bounds.size.width - indicatorF.size.width) / 2) + xPos;

    indicator.frame = indicatorF;

    yPos += indicatorF.size.height;

    

    if (labelSize.height >0.f && indicatorF.size.height >0.f) {

        yPos += kPadding;

    }

    CGRect labelF;

    labelF.origin.y = yPos;

    labelF.origin.x =round((bounds.size.width - labelSize.width) / 2) + xPos;

    labelF.size = labelSize;

    label.frame = labelF;

    yPos += labelF.size.height;

    

    if (detailsLabelSize.height >0.f && (indicatorF.size.height >0.f || labelSize.height >0.f)) {

        yPos += kPadding;

    }

    CGRect detailsLabelF;

    detailsLabelF.origin.y = yPos;

    detailsLabelF.origin.x =round((bounds.size.width - 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(self.bounds.size.width/2,self.bounds.size.height/2);

        //Gradient radius

        float gradRadius =MIN(self.bounds.size.width , self.bounds.size.height) ;

        //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((allRect.size.width - size.width) /2) + self.xOffset,

                                round((allRect.size.height -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 *keyPathin [selfobservableKeypaths]) {

        [selfaddObserver:selfforKeyPath:keyPath options:NSKeyValueObservingOptionNewcontext:NULL];

    }

}


- (void)unregisterFromKVO {

    for (NSString *keyPathin [selfobservableKeypaths]) {

        [selfremoveObserver:selfforKeyPath:keyPath];

    }

}


- (NSArray *)observableKeypaths {

    return [NSArrayarrayWithObjects:@"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 (![NSThreadisMainThread]) {

        [selfperformSelectorOnMainThread:@selector(updateUIForKeypath:)withObject:keyPath waitUntilDone:NO];

    } else {

        [selfupdateUIForKeypath:keyPath];

    }

}


- (void)updateUIForKeypath:(NSString *)keyPath {

    if ([keyPathisEqualToString:@"mode"] || [keyPathisEqualToString:@"customView"] ||

        [keyPath isEqualToString:@"activityIndicatorColor"]) {

        [selfupdateIndicators];

    } elseif ([keyPath isEqualToString:@"labelText"]) {

        label.text =self.labelText;

    } elseif ([keyPath isEqualToString:@"labelFont"]) {

        label.font =self.labelFont;

    } elseif ([keyPath isEqualToString:@"labelColor"]) {

        label.textColor =self.labelColor;

    } elseif ([keyPath isEqualToString:@"detailsLabelText"]) {

        detailsLabel.text =self.detailsLabelText;

    } elseif ([keyPath isEqualToString:@"detailsLabelFont"]) {

        detailsLabel.font =self.detailsLabelFont;

    } elseif ([keyPath isEqualToString:@"detailsLabelColor"]) {

        detailsLabel.textColor =self.detailsLabelColor;

    } elseif ([keyPath isEqualToString:@"progress"]) {

        if ([indicatorrespondsToSelector:@selector(setProgress:)]) {

            [(id)indicatorsetValue:@(progress)forKey:@"progress"];

        }

        return;

    }

    [selfsetNeedsLayout];

    [selfsetNeedsDisplay];

}


#pragma mark - Notifications


- (void)registerForNotifications {

    NSNotificationCenter *nc = [NSNotificationCenterdefaultCenter];

    

    [nc addObserver:selfselector:@selector(statusBarOrientationDidChange:)

               name:UIApplicationDidChangeStatusBarOrientationNotificationobject:nil];

}


- (void)unregisterFromNotifications {

    NSNotificationCenter *nc = [NSNotificationCenterdefaultCenter];

    [nc removeObserver:selfname:UIApplicationDidChangeStatusBarOrientationNotificationobject:nil];

}


- (void)statusBarOrientationDidChange:(NSNotification *)notification {

    UIView *superview =self.superview;

    if (!superview) {

        return;

    } elseif ([selfshouldPerformOrientationTransform]) {

        [selfsetTransformForCurrentOrientation:YES];

    } else {

        self.frame =self.superview.bounds;

        [selfsetNeedsDisplay];

    }

}


- (void)setTransformForCurrentOrientation:(BOOL)animated {

    // Stay in sync with the superview

    if (self.superview) {

        self.bounds =self.superview.bounds;

        [selfsetNeedsDisplay];

    }

    

    UIInterfaceOrientation orientation = [UIApplicationsharedApplication].statusBarOrientation;

    CGFloat radians =0;

    if (UIInterfaceOrientationIsLandscape(orientation)) {

        

        if (NSFoundationVersionNumber <=NSFoundationVersionNumber_iOS_7_1)

        {

            if (orientation ==UIInterfaceOrientationLandscapeLeft) { radians = -(CGFloat)M_PI_2; }

            else { radians = (CGFloat)M_PI_2; }

        }

        // Window coordinates differ!

        self.bounds =CGRectMake(0,0, self.bounds.size.height,self.bounds.size.width);

    } else {

        if (orientation ==UIInterfaceOrientationPortraitUpsideDown) { radians = (CGFloat)M_PI; }

        else { radians =0; }

    }

    rotationTransform =CGAffineTransformMakeRotation(radians);

    

    if (animated) {

        [UIViewbeginAnimations:nilcontext:nil];

        [UIViewsetAnimationDuration:0.3];

    }

    [selfsetTransform:rotationTransform];

    if (animated) {

        [UIViewcommitAnimations];

    }

}


@end



@implementation MBRoundProgressView


#pragma mark - Lifecycle


- (id)init {

    return [selfinitWithFrame:CGRectMake(0.f,0.f, 37.f, 37.f)];

}


- (id)initWithFrame:(CGRect)frame {

    self = [superinitWithFrame:frame];

    if (self) {

        self.backgroundColor = [UIColorclearColor];

        self.opaque =NO;

        _progress =0.f;

        _annular =NO;

        _progressTintColor = [[UIColoralloc] initWithWhite:1.falpha:1.f];

        _backgroundTintColor = [[UIColoralloc] initWithWhite:1.falpha:.1f];

        [selfregisterForKVO];

    }

    returnself;

}


- (void)dealloc {

    [selfunregisterFromKVO];

#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 = [UIBezierPathbezierPath];

        processBackgroundPath.lineWidth = lineWidth;

        processBackgroundPath.lineCapStyle =kCGLineCapButt;

        CGPoint center =CGPointMake(self.bounds.size.width/2,self.bounds.size.height/2);

        CGFloat radius = (self.bounds.size.width - lineWidth)/2;

        CGFloat startAngle = - ((float)M_PI /2); // 90 degrees

        CGFloat endAngle = (2 * (float)M_PI) + startAngle;

        [processBackgroundPath addArcWithCenter:centerradius:radius startAngle:startAngleendAngle:endAngle clockwise:YES];

        [_backgroundTintColorset];

        [processBackgroundPath stroke];

        // Draw progress

        UIBezierPath *processPath = [UIBezierPathbezierPath];

        processPath.lineCapStyle = isPreiOS7 ?kCGLineCapRound : kCGLineCapSquare;

        processPath.lineWidth = lineWidth;

        endAngle = (self.progress *2 * (float)M_PI) + startAngle;

        [processPath addArcWithCenter:centerradius:radius startAngle:startAngleendAngle:endAngle clockwise:YES];

        [_progressTintColorset];

        [processPath stroke];

    } else {

        // Draw background

        [_progressTintColorsetStroke];

        [_backgroundTintColorsetFill];

        CGContextSetLineWidth(context,2.0f);

        CGContextFillEllipseInRect(context, circleRect);

        CGContextStrokeEllipseInRect(context, circleRect);

        // Draw progress

        CGPoint center =CGPointMake(allRect.size.width /2, allRect.size.height /2);

        CGFloat radius = (allRect.size.width -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 *keyPathin [selfobservableKeypaths]) {

        [selfaddObserver:selfforKeyPath:keyPath options:NSKeyValueObservingOptionNewcontext:NULL];

    }

}


- (void)unregisterFromKVO {

    for (NSString *keyPathin [selfobservableKeypaths]) {

        [selfremoveObserver:selfforKeyPath:keyPath];

    }

}


- (NSArray *)observableKeypaths {

    return [NSArrayarrayWithObjects:@"progressTintColor",@"backgroundTintColor", @"progress", @"annular",nil];

}


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    [selfsetNeedsDisplay];

}


@end



@implementation MBBarProgressView


#pragma mark - Lifecycle


- (id)init {

    return [selfinitWithFrame:CGRectMake(.0f,.0f, 120.0f, 20.0f)];

}


- (id)initWithFrame:(CGRect)frame {

    self = [superinitWithFrame:frame];

    if (self) {

        _progress =0.f;

        _lineColor = [UIColorwhiteColor];

        _progressColor = [UIColorwhiteColor];

        _progressRemainingColor = [UIColorclearColor];

        self.backgroundColor = [UIColorclearColor];

        self.opaque =NO;

        [selfregisterForKVO];

    }

    returnself;

}


- (void)dealloc {

    [selfunregisterFromKVO];

#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,[_lineColorCGColor]);

    CGContextSetFillColorWithColor(context, [_progressRemainingColorCGColor]);

    

    // Draw background

    float radius = (rect.size.height /2) - 2;

    CGContextMoveToPoint(context,2, rect.size.height/2);

    CGContextAddArcToPoint(context,2, 2, radius +2, 2, radius);

    CGContextAddLineToPoint(context, rect.size.width - radius -2, 2);

    CGContextAddArcToPoint(context, rect.size.width -2, 2, rect.size.width -2, rect.size.height /2, radius);

    CGContextAddArcToPoint(context, rect.size.width -2, rect.size.height -2, rect.size.width - radius -2, rect.size.height -2, radius);

    CGContextAddLineToPoint(context, radius +2, rect.size.height -2);

    CGContextAddArcToPoint(context,2, rect.size.height -2, 2, rect.size.height/2, radius);

    CGContextFillPath(context);

    

    // Draw border

    CGContextMoveToPoint(context,2, rect.size.height/2);

    CGContextAddArcToPoint(context,2, 2, radius +2, 2, radius);

    CGContextAddLineToPoint(context, rect.size.width - radius -2, 2);

    CGContextAddArcToPoint(context, rect.size.width -2, 2, rect.size.width -2, rect.size.height /2, radius);

    CGContextAddArcToPoint(context, rect.size.width -2, rect.size.height -2, rect.size.width - radius -2, rect.size.height -2, radius);

    CGContextAddLineToPoint(context, radius +2, rect.size.height -2);

    CGContextAddArcToPoint(context,2, rect.size.height -2, 2, rect.size.height/2, radius);

    CGContextStrokePath(context);

    

    CGContextSetFillColorWithColor(context, [_progressColorCGColor]);

    radius = radius - 2;

    float amount =self.progress * rect.size.width;

    

    // Progress in the middle area

    if (amount >= radius +4 && amount <= (rect.size.width - radius -4)) {

        CGContextMoveToPoint(context,4, rect.size.height/2);

        CGContextAddArcToPoint(context,4, 4, radius +4, 4, radius);

        CGContextAddLineToPoint(context, amount,4);

        CGContextAddLineToPoint(context, amount, radius +4);

        

        CGContextMoveToPoint(context,4, rect.size.height/2);

        CGContextAddArcToPoint(context,4, rect.size.height -4, radius + 4, rect.size.height - 4, radius);

        CGContextAddLineToPoint(context, amount, rect.size.height -4);

        CGContextAddLineToPoint(context, amount, radius +4);

        

        CGContextFillPath(context);

    }

    

    // Progress in the right arc

    else if (amount > radius + 4) {

        float x = amount - (rect.size.width - radius -4);

        

        CGContextMoveToPoint(context,4, rect.size.height/2);

        CGContextAddArcToPoint(context,4, 4, radius +4, 4, radius);

        CGContextAddLineToPoint(context, rect.size.width - radius -4, 4);

        float angle = -acos(x/radius);

        if (isnan(angle)) angle =0;

        CGContextAddArc(context, rect.size.width - radius -4, rect.size.height/2, radius,M_PI, angle, 0);

        CGContextAddLineToPoint(context, amount, rect.size.height/2);

        

        CGContextMoveToPoint(context,4, rect.size.height/2);

        CGContextAddArcToPoint(context,4, rect.size.height -4, radius + 4, rect.size.height - 4, radius);

        CGContextAddLineToPoint(context, rect.size.width - radius -4, rect.size.height -4);

        angle = acos(x/radius);

        if (isnan(angle)) angle =0;

        CGContextAddArc(context, rect.size.width - radius -4, rect.size.height/2, radius, -M_PI, angle, 1);

        CGContextAddLineToPoint(context, amount, rect.size.height/2);

        

        CGContextFillPath(context);

    }

    

    // Progress is in the left arc

    else if (amount < radius + 4 && amount >0) {

        CGContextMoveToPoint(context,4, rect.size.height/2);

        CGContextAddArcToPoint(context,4, 4, radius +4, 4, radius);

        CGContextAddLineToPoint(context, radius +4, rect.size.height/2);

        

        CGContextMoveToPoint(context,4, rect.size.height/2);

        CGContextAddArcToPoint(context,4, rect.size.height -4, radius + 4, rect.size.height - 4, radius);

        CGContextAddLineToPoint(context, radius +4, rect.size.height/2);

        

        CGContextFillPath(context);

    }

}


#pragma mark - KVO


- (void)registerForKVO {

    for (NSString *keyPathin [selfobservableKeypaths]) {

        [selfaddObserver:selfforKeyPath:keyPath options:NSKeyValueObservingOptionNewcontext:NULL];

    }

}


- (void)unregisterFromKVO {

    for (NSString *keyPathin [selfobservableKeypaths]) {

        [selfremoveObserver:selfforKeyPath:keyPath];

    }

}


- (NSArray *)observableKeypaths {

    return [NSArrayarrayWithObjects:@"lineColor",@"progressRemainingColor",@"progressColor", @"progress", nil];

}


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    [selfsetNeedsDisplay];

}


@end





2018-06-17 11:27:29 fish_yan_ 阅读数 3168

枚举为一组相关的值定义了一个共同的类型,使你可以在你的代码中以类型安全的方式来使用这些值。

swift 中的枚举,比 oc 中的枚举更加强大。在 oc 中枚举的值只接受 Int 类型的值,但是在 swift 中可以接受很多基本类型的值,甚至是另一个枚举类型。swift 中的枚举是属于一等类型,具备 class 的很多特性,例如计算属性,构造函数等。

枚举的基本用法

enum CompassPoint {
    case north
    case south
    case east
    case west
}

在 swift 中的枚举支持多种类型,没有默认值,枚举之间也可以用逗号隔开

enum CompassPoint {
    case north, south, east, west
}

枚举的使用

let direction: CompassPoint = .east

枚举的关联值


enum Calculate {
    case add(Int)
    case reduce(Int)
}

let num: Calculate = .add(2)

switch num {
case .add(let a):
    print(a) // 2
default:
    break
}

这种用法可以在给枚举赋值的时候指定其中的关联值,在用 switch 的时候可以再把关联值带出来。

原始值

以第一个例子为例

1.

enum CompassPoint: String {
    case north = "north"
    case south = "south"
    case east = "east"
    case west = "west"
}

上例是以字符串作为原始值

2.

enum CompassPoint: Int {
    case north = 0
    case south = 1
    case east = 2
    case west = 3
}

上例是以Int值作为原始值

let direction: CompassPoint = .east
print(direction.rawValue) // 1."east" 2. 2

初始化枚举

let direction = CompassPoint(rawValue: "east") // 可选值,因为这是一个可是白的构造器,可能找不到与之匹配的枚举。

还有更高级的枚举用法在随后的章节中讲解。

2017-08-09 00:00:54 a997013919 阅读数 301


C中的枚举


在C语言中,甚至OC等其他高级语言中,都是把enum枚举的值当作是一个int整数来替代

具体可看我的这篇文章:C语言的枚举与宏定义



Swift中的枚举enum


注:本篇文章学习自泊学(boxueio.com)

(PS:Swift更新得真是非常快啊,4个月不到前写的代码,今天打开就提醒有语法要修正…)

1. what:

在Swift中,enum看起来是这样的:

enum Week{
    case MON
    case TUES
    case WED
    case THUR
    case FRI
    case SAT
    case SUN
}

let week1 = Week.MON

或:

enum Subject{
    case Chinese,English,Chemistry,History
}
let mySubject = Subject.Chinese

无论哪种方式,可以在playground看到,当在使用Week.MON时,就已经在访问一个enum的值了,它的case就是它的值本身,无需刻意地定义一个值来代表它。


2. why:

使用enum比使用字符串或数字有很多好处:

1 避免输入错误

2 使用enum类型是安全的,如当使用Week或Subject时,不会发生类型正确,值却没有意义的情况

3. how:

1)enum与switch

如果enum的类型可被推导出,则可在读取值的时候,省掉它类型的名字:

func week(today: Week)
{
    switch today{
    // 因为today可以通过类型推导推出它的类型是Week,所以不用today.MON,而是直接写.MON
    case .MON, .TUES, .WED:
        return
    case .THUR, .FRI, .SAT, .SUN:
        return
    }
}

对于一个enum的switch来说,它的所有的case就是它全部的情况,所以最后不用再写default


2)enum值的表达方式1:raw value原始数值

1. 手动为enum指定值

enum Week:Int{
    case MON   = 2
    case TUES  = 4
    case WED   = 7
    case THUR
    case FRIFRI
    case SAT
    case SUN
}

2. 自动:

如上段代码,当没有手动为后面的THUR、FRI等赋值时,它们将被自动赋值,从上一个值开始递增

3. 访问enum的rawValue:

let week1 = Week.FRI.rawValue
此时为9

4. 用rawValue来访问一个enum的值

let week2 = Week(rawValue: 7)
此时enum值为WED


3)enum值的表达方式2: associated value结合值

1.  给每一个case绑定不同类型的值

enum HTTPAction{
    case GET  // 不关联任何值
    case POST(String)// 关联一个字符串
    case PUT(Int, String)// 关联一个tuple
}

let get = HTTPAction.GET
let post = HTTPAction.POST("hello")
let put = HTTPAction.PUT(1, "world")


2.  通过switch访问enum的结合值associated value

func actionDesc(action: HTTPAction)
{
    switch action
    {
    case .GET:
        print("get")
    case let .POST(msg):// let msg = action
        print("post: \(msg)")
    case .PUT(let num, let name):
        print("put: \(num): \(name)")
    }
}

actionDesc(action: get)
actionDesc(action: post)
actionDesc(action: put)







Swift 中调用OC枚举

阅读数 152

没有更多推荐了,返回首页