簡單實現 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還需要很多各方面的考慮