關(guān)于runtime的介紹這里就不做記錄了倍奢,簡書內(nèi)搜索 “runtime”一大堆七芭。曽看到過一篇介紹runtime的文章片习,末尾寫了一句話:用runtime如果不是為了裝X匪凉,那將毫無意義枪眉。那么今天,我就裝一回再层,用一個實際的需求(每個項目都能用到哦)來驗證runtime的作用之一 贸铜,給分類動態(tài)添加屬性。
需求:當(dāng)網(wǎng)絡(luò)連接錯誤或者接口返回 code= 0 的時候聂受,頁面如下:
有人說了蒿秦,嗨,就這個需求......的確饺饭,就這個需求渤早,但今天是通過runtime來實現(xiàn)职车。
1.準(zhǔn)備工作:準(zhǔn)備一個xib視圖
2 新建一個UIView的分類 UIView+State
UIView+State.h 文件代碼如下
#import <UIKit/UIKit.h>
@protocol UIViewStateDelegate <NSObject>
@optional
- (void)xs_noNetWorkViewStateShouldChnaged; //點擊刷新頁面代理
@end
@interface UIView (State)
@property (weak, nonatomic) id<UIViewStateDelegate> stateDelegate;
- (void)xs_switchToNoNetWorkState;//當(dāng)網(wǎng)絡(luò)連接錯誤時加載NoNetworkView
- (void)xs_switchToContentState;//當(dāng)網(wǎng)絡(luò)連接正常時移除NoNetworkView
@end
UIView+State.m文件代碼如下
#import "UIView+State.h"
#import <objc/runtime.h>//必須導(dǎo)入
@interface UIView ()
@property (strong, nonatomic) UIView *noNetworkView;//添加屬性
@end
@implementation UIView (State)
- (void)xs_switchToNoNetWorkState {
if (self.noNetworkView == nil) {
self.noNetworkView = [[[NSBundle mainBundle] loadNibNamed:@"NoNetWorkView" owner:nil options:nil] objectAtIndex:0];
}
[self addSubview:self.noNetworkView];
[self bringSubviewToFront:self.noNetworkView];
self.noNetworkView.frame = self.bounds;
if (self.stateDelegate && [self.stateDelegate respondsToSelector:@selector(xs_noNetWorkViewStateShouldChnaged)]) {
self.noNetworkView.userInteractionEnabled = YES;
[self.noNetworkView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self.stateDelegate action:@selector(xs_noNetWorkViewStateShouldChnaged)]];//添加點擊手勢
}
}
- (void)xs_switchToContentState {
[self.noNetworkView removeFromSuperview];
}
#pragma mark - getters and setters
//關(guān)聯(lián)
//objc_setAssociatedObject來把一個對象與另外一個對象進(jìn)行關(guān)聯(lián)瘫俊。該函數(shù)需要四個參數(shù):源對象,關(guān)鍵字悴灵,關(guān)聯(lián)的對象和一個關(guān)聯(lián)策略
static char stateDelegateKey;
- (id<UIViewStateDelegate>)stateDelegate {
return objc_getAssociatedObject(self, &stateDelegateKey);
}
- (void)setStateDelegate:(id<UIViewStateDelegate>)stateDelegate {
objc_setAssociatedObject(self, &stateDelegateKey, stateDelegate, OBJC_ASSOCIATION_ASSIGN);
}
static char noNetWorkViewKey;
- (UIView *)noNetworkView {
return objc_getAssociatedObject(self, &noNetWorkViewKey);
}
- (void)setNoNetworkView:(UIView *)noNetworkView {
objc_setAssociatedObject(self, &noNetWorkViewKey, noNetworkView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
3.UIView+State 分類的使用
3.1在controller.m中 先導(dǎo)入文件
#import "UIView+State.h"
3.2 遵循代理
@interface ZLMComplainListViewController ()<UIViewStateDelegate>
- (void)viewDidLoad {
[super viewDidLoad];
self.view.stateDelegate = self;
}
3.3 在適當(dāng)條件下調(diào)分類方法
-(void)loadData:(NSInteger )page{
NSString *urlStr = [NSString stringWithFormat:@"%@/complaint/list", host];
NSDictionary *param = @{
@"page":@(page)
};
if (page == 1) {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
}
XSAPIManager *manager = [XSAPIManager manager];
[manager GET:urlStr parameters:param success:^(id responseObject) {
self.complainListBridge = [ComplainList mj_objectWithKeyValues:responseObject];//將json數(shù)據(jù)映射到model中
if (self.complainListBridge.code == 1) {
[self.view xs_switchToContentState];//如果網(wǎng)絡(luò)請求成功并返回code=1扛芽,移除網(wǎng)絡(luò)連接錯誤的視圖
} else {
[self.view xs_switchToNoNetWorkState];//返回code= 0 ,加載網(wǎng)絡(luò)連接的視圖
}
[self.tableview reloadData];
[MBProgressHUD hideAllHUDsForView:weakSelf.view animated:YES];
} failure:^(NSError *error) {
[MBProgressHUD hideAllHUDsForView:weakSelf.view animated:YES];
[self.view xs_switchToNoNetWorkState];//網(wǎng)絡(luò)連接錯誤 积瞒,加載網(wǎng)絡(luò)連接的視圖
}];
}
3.4 實現(xiàn)代理方法 點擊刷新
#pragma mark - UIViewStateDelegate
- (void)xs_noNetWorkViewStateShouldChnaged {
[self loadData:1];
}
通過以上介紹川尖,是不是可以舉一反三呢?當(dāng)沒收藏列表中沒收藏茫孔,地址列表中沒地址叮喳,訂單列表中沒訂單等等等等被芳,趕緊用起來吧。
以上馍悟。