我也玩下runtime(干货)

关于runtime的介绍这里就不做记录了,内搜索 “runtime”一大堆。曽看到过一篇介绍runtime的文章,末尾写了一句话:用runtime如果不是为了装X,那将毫无意义。那么今天,我就装一回,用一个实际的需求(每个项目都能用到哦)来验证runtime的作用之一 ,给分类动态添加属性。

需求:当网络连接错误或者接口返回 code= 0 的时候,页面如下:


我也玩下runtime(干货)_第1张图片
网络请求失败.png

有人说了,嗨,就这个需求......的确,就这个需求,但今天是通过runtime来实现。

1.准备工作:准备一个xib视图

我也玩下runtime(干货)_第2张图片
NoNetWorkView.xib.png

2 新建一个UIView的分类 UIView+State
UIView+State.h 文件代码如下

#import 

@protocol UIViewStateDelegate 
@optional
- (void)xs_noNetWorkViewStateShouldChnaged; //点击刷新页面代理
@end

@interface UIView (State)

@property (weak, nonatomic) id stateDelegate;

- (void)xs_switchToNoNetWorkState;//当网络连接错误时加载NoNetworkView

- (void)xs_switchToContentState;//当网络连接正常时移除NoNetworkView

@end

UIView+State.m文件代码如下

#import "UIView+State.h"
#import //必须导入

@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
//关联
//objc_setAssociatedObject来把一个对象与另外一个对象进行关联。该函数需要四个参数:源对象,关键字,关联的对象和一个关联策略
static char stateDelegateKey;
- (id)stateDelegate {
    return objc_getAssociatedObject(self, &stateDelegateKey);
}

- (void)setStateDelegate:(id)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中 先导入文件

#import "UIView+State.h"

3.2 遵循代理

@interface ZLMComplainListViewController ()

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.stateDelegate = self;
  }

3.3 在适当条件下调分类方法

-(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数据映射到model中
      
        if (self.complainListBridge.code == 1) {
            
            [self.view xs_switchToContentState];//如果网络请求成功并返回code=1,移除网络连接错误的视图

        } else {
            [self.view xs_switchToNoNetWorkState];//返回code= 0  ,加载网络连接的视图
        }
       [self.tableview reloadData];
       
        [MBProgressHUD hideAllHUDsForView:weakSelf.view animated:YES];
    } failure:^(NSError *error) {
        [MBProgressHUD hideAllHUDsForView:weakSelf.view animated:YES];
         [self.view xs_switchToNoNetWorkState];//网络连接错误 ,加载网络连接的视图
        
    }];

}

3.4 实现代理方法 点击刷新

#pragma mark - UIViewStateDelegate
- (void)xs_noNetWorkViewStateShouldChnaged {
    [self loadData:1];
}

通过以上介绍,是不是可以举一反三呢?当没收藏列表中没收藏,地址列表中没地址,订单列表中没订单等等等等,赶紧用起来吧。

以上。

你可能感兴趣的:(我也玩下runtime(干货))