如何設計一個好的第三方框架給別其他開發(fā)者用?需要要考慮哪些方面?
- 如圖:一個簡易的狀態(tài)欄的hud示例,通過這個示例了解在設計第三方框架需要注意哪些方面
demo.gif
一.框架的名字
-
DXStatusBarHUD
,前綴自定義,比如自己的名字縮寫,StatusBarHUD
名字中要能顯示出框架的功能
二.設計對外的接口
- 首先考慮外界如何調(diào)用方便
- 其次要考慮性能最好,優(yōu)先考慮類方法,如--> 類名 + 方法
1.外界調(diào)用的方法
- (IBAction)success {
[DXStatusBarHUD showSuccess:@"加載數(shù)據(jù)成功!"];
}
- (IBAction)error {
[DXStatusBarHUD showError:@"登錄失旈稀!"];
}
- (IBAction)loading {
[DXStatusBarHUD showLoading:@"正在登錄中..."];
}
- (IBAction)hide {
[DXStatusBarHUD hide];
}
- (IBAction)normal {
[DXStatusBarHUD showText:@"隨便顯示的文字!!P裱省浅乔!"];
}
2.對外提供的方法
- 注意:
- 盡量用文檔注釋,這樣書寫有提示
- 用戶不傳圖片,默認提供圖片
- 要考慮到外界更改提示框圖片的情況
- 注意對外提供的接口和參數(shù)應該盡量少
- 要考慮到用戶不停的點擊或者亂點擊等各種情況,需多作判斷
/*此方法設計缺點:只能加載本地圖片,不能加載網(wǎng)絡圖片,例如用SD_webImage下載保存到沙盒的圖片
* 顯示圖片+文字信息
*/
+ (void)showImageName:(NSString *)imageName text:(NSString *)text;
/**
* 顯示圖片+文字信息
*/
+ (void)showImage:(UIImage *)image text:(NSString *)text;
/**
* 顯示成功信息
*/
+ (void)showSuccess:(NSString *)text;
/**
* 顯示失敗信息
*/
+ (void)showError:(NSString *)text;
/**
* 顯示正在處理的信息
*/
+ (void)showLoading:(NSString *)text;
/**
* 顯示普通信息
*/
+ (void)showText:(NSString *)text;
/**
* 隱藏
*/
+ (void)hide;
3.方法的實現(xiàn)
- 注意:
- 在類方法中不能調(diào)用對象的屬性,如果想要保住一個對象的命,可以用全局變量;
- 一些常量推薦使用
static
修飾的全局常量,而不使用宏 - 注釋要簡明扼要,減少不必要的注釋
- 注意代碼的封裝,重構
- 注意代碼的可擴展性,方便其他開發(fā)者可以給這個框架添加新功能
- 注意定時器的使用,不用的時候要清空
static UIWindow *window_;
static NSTimer *timer_;
/** HUD控件的高度 */
static CGFloat const DXWindowH = 20;
/** HUD控件的動畫持續(xù)時間(出現(xiàn)\隱藏) */
static CGFloat const DXAnimationDuration = 0.25;
/** HUD控件默認會停留多長時間 */
static CGFloat const DXHUDStayDuration = 1.5;
+ (void)showImage:(UIImage *)image text:(NSString *)text
{
// 停止之前的定時器
[timer_ invalidate];
// 創(chuàng)建窗口
window_.hidden = YES; // 先隱藏之前的window
window_ = [[UIWindow alloc] init];
window_.backgroundColor = [UIColor blackColor];
window_.windowLevel = UIWindowLevelAlert;
window_.frame = CGRectMake(0, - DXWindowH, [UIScreen mainScreen].bounds.size.width, DXWindowH);
window_.hidden = NO;
// 添加按鈕
UIButton *button = [[UIButton alloc] init];
button.frame = window_.bounds;
// 文字
[button setTitle:text forState:UIControlStateNormal];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize:13];
// 圖片
if (image) {
[button setImage:image forState:UIControlStateNormal];
button.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 5);
button.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 0, 0);
}
[window_ addSubview:button];
// 動畫
[UIView animateWithDuration:DXAnimationDuration animations:^{
CGRect frame = window_.frame;
frame.origin.y = 0;
window_.frame = frame;
}];
// 開啟一個新的定時器
timer_ = [NSTimer scheduledTimerWithTimeInterval:DXHUDStayDuration target:self selector:@selector(hide) userInfo:nil repeats:NO];
}
+ (void)showImageName:(NSString *)imageName text:(NSString *)text
{
[self showImage:[UIImage imageNamed:imageName] text:text];
}
+ (void)showSuccess:(NSString *)text
{
[self showImageName:@"DXStatusBarHUD.bundle/success" text:text];
}
+ (void)showError:(NSString *)text
{
[self showImageName:@"DXStatusBarHUD.bundle/error" text:text];
}
+ (void)showText:(NSString *)text
{
[self showImage:nil text:text];
}
+ (void)showLoading:(NSString *)text
{
// 停止之前的定時器
[timer_ invalidate];
timer_ = nil;
// 創(chuàng)建窗口
window_.hidden = YES; // 先隱藏之前的window
window_ = [[UIWindow alloc] init];
window_.backgroundColor = [UIColor blackColor];
window_.windowLevel = UIWindowLevelAlert;
window_.frame = CGRectMake(0, - DXWindowH, [UIScreen mainScreen].bounds.size.width, DXWindowH);
window_.hidden = NO;
// 添加按鈕
UIButton *button = [[UIButton alloc] init];
button.frame = window_.bounds;
// 文字
[button setTitle:text forState:UIControlStateNormal];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize:13];
[window_ addSubview:button];
// 圈圈
UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[loadingView startAnimating];
loadingView.center = CGPointMake(button.titleLabel.frame.origin.x - 60, DXWindowH * 0.5);
[window_ addSubview:loadingView];
// 動畫
[UIView animateWithDuration:DXAnimationDuration animations:^{
CGRect frame = window_.frame;
frame.origin.y = 0;
window_.frame = frame;
}];
}
+ (void)hide
{
// 清空定時器
[timer_ invalidate];
timer_ = nil;
// 退出動畫
[UIView animateWithDuration:DXAnimationDuration animations:^{
CGRect frame = window_.frame;
frame.origin.y = - DXWindowH;
window_.frame = frame;
} completion:^(BOOL finished) {
window_ = nil;
}];
}
三.關于圖片資源處理
- 對應圖片資源,應該注意框架內(nèi)部圖片名稱不能出現(xiàn)與使用者圖片名稱一樣,為解決可能出現(xiàn)圖片名稱一樣,可以對圖片文件夾打包成bundle文件,如圖
pic.png
四.簡單易用
- 要減少開發(fā)者的項目的侵入性,比如不需要開發(fā)者的類繼承框架內(nèi)部的類
- 提供一個demo供開發(fā)者快速上手
- 開發(fā)者使用:
1.把框架文件拽入自己項目中
2.導入頭文件
3.查看頭文件的方法,直接調(diào)用