OC--链式编程学习(简单封装MBProgressHUD用例)

学习OC下的链式编程实战

简单实现
BBPerson.h

#import <Foundation/Foundation.h>

@class BBPerson;

typedef BBPerson *(^BBChainStringBlock)(NSString *);

@interface BBPerson : NSObject

@property (nonatomic, strong) NSString *nameString;/**<  */
@property (nonatomic, strong) NSString *ageString;/**<  */

- (BBChainStringBlock)name;
- (BBChainStringBlock)age;

@end

BBPerson.m

#import "BBPerson.h"

@implementation BBPerson


- (BBChainStringBlock)name {
    
    BBChainStringBlock block = ^(NSString * aString) {
        
        _nameString = aString;
        return self;
    };
    return block;
    
}

- (BBChainStringBlock)age {
    
    BBChainStringBlock block = ^(NSString * aString) {
        
        _ageString = aString;
        return self;
    };
    return block;
    
}

@end

使用例子

    BBPerson *person = [BBPerson new];
    // 使用方式可以如下:
    person.age(@"18");
    person.name(@"XXX");
    person.name(@"XXX").age(@"18");
    person.age(@"18").name(@"XXX");

    NSLog(@"nameString=%@ ageString=%@",person.nameString,person.ageString);
    
    // 解析:
    // 其实person.name返回一个block,
    BBChainStringBlock nameBlock = person.name;
    nameBlock(@"XXX");// 这个block就是把 _nameString = @"XXX"; return self;
    nameBlock(@"XXX").age(@"18");// nameBlock(@"XXX")是返回self,即使person对象,所以可以链式编程

增加一个make方法

+ (BBPerson *)makeConstraints:(void(^)(BBPerson *))block {
    
    BBPerson *person = [[BBPerson alloc] init];
    block(person);
    
    return person;
}

使用make方法

    // 就这么new一个person实例了
    BBPerson *person = [BBPerson makeConstraints:^(BBPerson *maker) {
        maker.name(@"WWW").age(@"18");
    }];
    // 以后需要括展属性,比如性别sex,写好sex的block
    BBPerson *person1 = [BBPerson makeConstraints:^(BBPerson *maker) {
        maker.name(@"WWW").age(@"18").sex(@"男");
    }];

真实项目开发过程中,为了避免第三方库入侵项目代码内部,经常需要进一步封装第三方库:
1.项目与第三方尽量解耦,
2.使用、修改替换方便。

OC的封装就是各种条件都写好,参数少还可以,参数多封装的方法就多。
比如封装一下MBProgressHUD:动画参数、时间参数、显示的文字、显示在哪个view上、显示自定义的小图片、能不能操作hud背后界面。如果把这些参数都各种全组合方法一个一个写,那要死人哦。

// 一般的show,有各种组合、有maskType--能操作、不能操作
+ (void)show;
+ (void)showWithMaskType:(PSProgressHUDMaskType)maskType;
+ (void)showWithStatus:(NSString*)status;
+ (void)showWithStatus:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;
+ (void)showProgress:(float)progress;
+ (void)showProgress:(float)progress maskType:(PSProgressHUDMaskType)maskType;
+ (void)showProgress:(float)progress status:(NSString*)status;
+ (void)showProgress:(float)progress status:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;
+ (void)showInfoWithStatus:(NSString*)status;
+ (void)showInfoWithStatus:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;
+ (void)showSuccessWithStatus:(NSString*)status;
+ (void)showSuccessWithStatus:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;
+ (void)showErrorWithStatus:(NSString*)status;
+ (void)showErrorWithStatus:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;
+ (void)showStatus:(NSString*)status;
+ (void)showStatus:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;
+ (void)showImage:(UIImage*)image status:(NSString*)status;
+ (void)showImage:(UIImage*)image status:(NSString*)status maskType:(PSProgressHUDMaskType)maskType;

如果使用链式编程,就可以解决参数过多的麻烦了。

然后自己试着用链式编程方式,封装一下MBProgressHUD

直接上代码

MBProgressHUD.h
#import <Foundation/Foundation.h>
#import "MBProgressHUD.h"

#define kPSProgressHUD [PSProgressHUD new]

typedef NS_ENUM(NSUInteger, PSHUDMaskType) {
    PSHUDMaskType_None = 0,  //允许操作其他UI
    PSHUDMaskType_Clear,     //不允许操作
};

typedef NS_ENUM(NSUInteger, PSHUDInViewType) {
    PSHUDInViewType_KeyWindow = 0,  //UIApplication.KeyWindow
    PSHUDInViewType_CurrentView,    //CurrentViewController.view
};

typedef NS_ENUM(NSUInteger, PSProgressType) {
    PSProgressType_HorizontalBar = 0,  //水平进度条
    PSProgressType_AnnularBar,    //环形进度条
};

//PSProgressHUD链式编程语法的使用🌰
/*
 一、Loading
 
 显示:[PSProgressHUD showLoadingCalculators:^(PSProgressHUD *make) {
          make.inViewType(PSHUDInViewType_CurrentView).message(@"你好吗?");
       }];
 消失:[PSProgressHUD cancelLoadingCalculators:^(PSProgressHUD *make) {
          make.inViewType(PSHUDInViewType_CurrentView);
       }];
 
 
 
 二、showHandleMessage
 
 显示:[PSProgressHUD showHandleMessageCalculators:^(PSProgressHUD *make) {
          make.afterDelay(10).message(@"你好啊");
      }];


 
 三、showUploadProgress
 
 使用:MBProgressHUD *hud=[PSProgressHUD showUploadProgressCalculators:^(PSProgressHUD *make) {
                             make.inViewType(PSHUDInViewType_CurrentView).message(@"我是进度条");
                          }];
 
 更新进度条:hud.progress=0.5;
 
 消失:
 (1)[hud hideAnimated:YES]; (直接使用就可以,前面已经生成MBProgressHUD *hud)
 (2)[PSProgressHUD cancelUploadProgressCalculators:^(PSProgressHUD *make) {
         make.inViewType(PSHUDInViewType_CurrentView);
      }];
 */


@interface PSProgressHUD : NSObject



/**
 显示Loading HUD
 @param block 配置各种参数
 @return MBProgressHUD对象
 */
+ (MBProgressHUD *)showLoadingCalculators:(void (^)(PSProgressHUD * make))block;


/**
 消失Loading HUD
 @param block 必须配置与showLoading对应的InView
 */
+ (void)cancelLoadingCalculators:(void (^)(PSProgressHUD * make))block;


/**
 显示HandleMessage HUD
 @param block 配置各种参数
 @return MBProgressHUD对象
 */
+ (MBProgressHUD *)showHandleMessageCalculators:(void (^)(PSProgressHUD * make))block;


/**
 显示Loading HUD
 @param block 配置各种参数
 @return MBProgressHUD对象
 */
+ (MBProgressHUD *)showUploadProgressCalculators:(void (^)(PSProgressHUD * make))block;
/**
 消失UploadProgress HUD
 @param block 必须配置与showUploadProgress对应的InView
 */
+ (void)cancelUploadProgressCalculators:(void (^)(PSProgressHUD * make))block;


#pragma mark - 下面的代码,就是设置保存相应的参数,返回self,
// self=self.message(@"文字"),分两步
// (1)第一步:self.message首先是返回一个block;
// (2)第二步:self=self.messageblock(@"文字") block里面是{ self.msg=@"文字"; 返回self }.
// 对应一般的语法就是:self=[self message:@"文字"];就是这么个意思
/**
 .showMessage(@"需要显示的文字")
 */
- (PSProgressHUD *(^)(NSString *))message;

/**
 .animated(YES)是否动画,YES动画,NO不动画
 */
- (PSProgressHUD *(^)(BOOL))animated;

/**
 .inView(view)
 有特殊需要inView的才使用,一般使用.inViewType()
 */
- (PSProgressHUD *(^)(UIView *))inView;

/**
 .inViewType(inViewType) 指定的InView
 PSHUDInViewType_KeyWindow--KeyWindow,配合MaskType_Clear,就是全部挡住屏幕不能操作了,只能等消失
 PSHUDInViewType_CurrentView--当前的ViewController,配合MaskType_Clear,就是view不能操作,但是导航栏能操作(例如返回按钮)。
 */
- (PSProgressHUD *(^)(PSHUDInViewType))inViewType;

/**
 .maskType(MaskType) HUD显示是否允许操作背后,
 PSHUDMaskType_None:允许
 PSHUDMaskType_Clear:不允许
 */
- (PSProgressHUD *(^)(PSHUDMaskType))maskType;

/**
 .customView(view),设置customView
 注:只对.showMessage(@"")有效
 */
- (PSProgressHUD *(^)(UIView *))customView;

/**
 .customView(iconName),带有小图标、信息, 
 iconName:小图标名字
 注:只对.showMessage(@"")有效
 */
- (PSProgressHUD *(^)(NSString *))customIconName;

/**
 .afterDelay(2)消失时间,默认是2秒
 注:只对.showHandleMessageCalculators有效
 */
- (PSProgressHUD *(^)(NSTimeInterval))afterDelay;


/**
 progressType()设置进度条类型
 PSProgressType_HorizontalBar--水平进度条
 PSProgressType_AnnularBar-----环形进度条
 注:只对.showUploadProgressCalculators有效
 */
- (PSProgressHUD *(^)(PSProgressType))progressType;
MBProgressHUD.m
#import "PSProgressHUD.h"
#import "UIApplication+AppRootViewController.h"

@interface PSProgressHUD ()
{
    
}
//全都可以使用的参数
@property(nonatomic, strong) UIView *ps_inView;/**<hud加在那个view上*/
@property(nonatomic, assign) BOOL ps_animated;/**<是否动画显示、消失*/
@property(nonatomic, assign) PSHUDMaskType ps_maskType;/**<hud背后的view是否还可以操作*/

//只有showHandleMessage可以使用的属性
@property(nonatomic, strong) UIView *ps_customView;/**<自定义的view*/
@property(nonatomic, strong) NSString *ps_customIconName;/**<自定义的小图标*/
@property(nonatomic, strong) NSString *ps_message;/**<hud上面的文字*/
@property(nonatomic, assign) NSTimeInterval ps_afterDelay;/**<自动消失时间*/

//只有进度条使用的
@property(nonatomic, assign) PSProgressType ps_progressType;/**<进度条类型:水平横条或者圆形*/

@end

@implementation PSProgressHUD

//简单的显示方法
+ (MBProgressHUD *)showLoading:(NSString *)loadingString{
    return [PSProgressHUD showLoadingCalculators:^(PSProgressHUD *make) {
        make.message(loadingString);
    }];
}
+ (MBProgressHUD *)showLoadingInKeyWindow:(NSString *)loadingString{
    return [PSProgressHUD showLoadingCalculators:^(PSProgressHUD *make) {
        make.message(loadingString).inViewType(PSHUDInViewType_KeyWindow);
    }];
}
+ (MBProgressHUD *)showLoadingCurrentView:(NSString *)loadingString{
    return [PSProgressHUD showLoadingCalculators:^(PSProgressHUD *make) {
        make.message(loadingString).inViewType(PSHUDInViewType_CurrentView);
    }];
}

+ (MBProgressHUD *)showLoadingCalculators:(void (^)(PSProgressHUD * make))block {
    //这就是block作为方法参数的用法,平时比较少写,感觉有点绕,脑袋转不过来。
//    void (^block)(PSProgressHUD * make)=^(PSProgressHUD *make) {
//        //这里可以链式语法,设置各种参数
//        make.inViewType(PSHUDInViewType_CurrentView).message(@"你好吗?");
//    };
    
    PSProgressHUD *makeObj = [[PSProgressHUD alloc] init];
    block(makeObj);
    __block MBProgressHUD *hud = nil;
    dispatch_async(dispatch_get_main_queue(), ^{
        MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:makeObj.ps_inView animated:makeObj.ps_animated];
        hud.label.text=makeObj.ps_message;
        hud.mode = MBProgressHUDModeIndeterminate;
        hud.minSize=CGSizeMake(120, 100);
        hud.userInteractionEnabled=makeObj.ps_animated;
    });
    return hud;
}


+ (void)cancelLoading{
    
    [PSProgressHUD cancelLoadingCalculators:^(PSProgressHUD *make) {}];
}
+ (void)cancelLoadingInKeyWindow{
    [PSProgressHUD cancelLoadingCalculators:^(PSProgressHUD *make) {
        make.inViewType(PSHUDInViewType_KeyWindow);
    }];
}
+ (void)cancelLoadingCurrentView{
    [PSProgressHUD cancelLoadingCalculators:^(PSProgressHUD *make) {
        make.inViewType(PSHUDInViewType_CurrentView);
    }];
}


+ (void)cancelLoadingCalculators:(void (^)(PSProgressHUD * make))block {
    
    PSProgressHUD *makeObj = [[PSProgressHUD alloc] init];
    block(makeObj);
    [MBProgressHUD hideHUDForView:makeObj.ps_inView animated:makeObj.ps_animated];
}


+ (MBProgressHUD *)showHandleMessage:(NSString *)handleMsg{
    
    return [PSProgressHUD showHandleMessageCalculators:^(PSProgressHUD *make) {
        make.message(handleMsg);
    }];
}

+ (MBProgressHUD *)showHandleMessageInKeyWindow:(NSString *)handleMsg{
    return [PSProgressHUD showHandleMessageCalculators:^(PSProgressHUD *make) {
        make.message(handleMsg).inViewType(PSHUDInViewType_KeyWindow);;
    }];
}
+ (MBProgressHUD *)showHandleMessageCurrentView:(NSString *)handleMsg{
    
    return [PSProgressHUD showHandleMessageCalculators:^(PSProgressHUD *make) {
        make.message(handleMsg).inViewType(PSHUDInViewType_CurrentView);;
    }];
}


+ (MBProgressHUD *)showHandleMessageCalculators:(void (^)(PSProgressHUD * make))block {
    
    PSProgressHUD *makeObj = [[PSProgressHUD alloc] init];
    block(makeObj);
    __block MBProgressHUD *hud = nil;
    dispatch_async(dispatch_get_main_queue(), ^{
        hud = [MBProgressHUD showHUDAddedTo:makeObj.ps_inView animated:makeObj.ps_animated];
        hud.label.text=makeObj.ps_message;
        hud.mode = MBProgressHUDModeText;
        hud.userInteractionEnabled=makeObj.ps_maskType;
        if (makeObj.ps_customView) {
            hud.customView = makeObj.ps_customView;
            hud.mode = MBProgressHUDModeCustomView;
        }else if (makeObj.ps_customIconName) {
            hud.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:makeObj.ps_customIconName]];
            hud.mode = MBProgressHUDModeCustomView;
        }
        [hud hideAnimated:makeObj.ps_animated afterDelay:makeObj.ps_afterDelay];
    });
    return hud;
}

+ (MBProgressHUD *)showUploadProgress:(NSString *)msg{
    
    return [PSProgressHUD showUploadProgressCalculators:^(PSProgressHUD *make) {
        make.message(msg);
    }];
}

+ (MBProgressHUD *)showUploadProgressCalculators:(void (^)(PSProgressHUD * make))block{
    
    PSProgressHUD *makeObj = [[PSProgressHUD alloc] init];
    block(makeObj);
    __block MBProgressHUD *hud = nil;
    dispatch_async(dispatch_get_main_queue(), ^{
        hud = [MBProgressHUD showHUDAddedTo:makeObj.ps_inView animated:makeObj.ps_animated];
        hud.label.text=makeObj.ps_message;
        hud.tag=88888;
        hud.mode = MBProgressHUDModeText;
        hud.userInteractionEnabled=makeObj.ps_maskType;
        if (makeObj.ps_progressType==PSProgressType_HorizontalBar) {
            hud.mode = MBProgressHUDModeDeterminateHorizontalBar;
        }else if (makeObj.ps_progressType==PSProgressType_AnnularBar) {
            hud.mode = MBProgressHUDModeAnnularDeterminate;
        }
    });
    return hud;
}
+ (void)cancelUploadProgressCalculators:(void (^)(PSProgressHUD * make))block {
    
    PSProgressHUD *makeObj = [[PSProgressHUD alloc] init];
    block(makeObj);
    MBProgressHUD *hud = (MBProgressHUD *)[makeObj.ps_inView viewWithTag:88888];
    [hud hideAnimated:makeObj.ps_animated];
}

- (instancetype)init{
    
    self=[super init];
    if (self) {//这里可以设置一些默认的属性
        _ps_inView=[UIApplication sharedApplication].keyWindow;
        _ps_maskType=PSHUDMaskType_None;
        _ps_afterDelay=2;
    }
    return self;
}

- (PSProgressHUD *(^)(UIView *))inView{
    return ^PSProgressHUD *(id obj) {
        _ps_inView=obj;
        return self;
    };
}

- (PSProgressHUD *(^)(UIView *))customView{
    return ^PSProgressHUD *(id obj) {
        _ps_customView=obj;
        return self;
    };
}

- (PSProgressHUD *(^)(NSString *))customIconName{
    return ^PSProgressHUD *(id obj) {
        _ps_customIconName=obj;
        return self;
    };
}

- (PSProgressHUD *(^)(PSHUDInViewType))inViewType{
    
    return ^PSProgressHUD *(PSHUDInViewType inViewType) {
        
        if (inViewType==PSHUDInViewType_KeyWindow) {
            _ps_inView=[UIApplication sharedApplication].keyWindow;
        }else if(inViewType==PSHUDInViewType_CurrentView){
            _ps_inView=[UIApplication currentViewController].view;
        }
        return self;
    };
}


- (PSProgressHUD *(^)(BOOL))animated{
    return ^PSProgressHUD *(BOOL animated) {
        _ps_animated=animated;
        return self;
    };
}

- (PSProgressHUD *(^)(PSHUDMaskType))maskType{
    return ^PSProgressHUD *(PSHUDMaskType maskType) {
        _ps_maskType=maskType;
        return self;
    };
}

- (PSProgressHUD *(^)(NSTimeInterval))afterDelay{
    return ^PSProgressHUD *(NSTimeInterval afterDelay) {
        _ps_afterDelay=afterDelay;
        return self;
    };
}

- (PSProgressHUD *(^)(NSString *))message{
    
    return ^PSProgressHUD *(NSString *msg) {
        _ps_message=msg;
        return self;
    };
}


- (PSProgressHUD *(^)(PSProgressType))progressType{
    
    return ^PSProgressHUD *(PSProgressType progressType) {
        _ps_progressType=progressType;
        return self;
    };
    
}

@end

现在只是学习一下链式编程的,如果完善封装MBProgressHUD还需要很多各方面的考虑

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容