封装AFN3.1并且封装自定义alertView

  • 作者:王颖博
  • 最后编辑:2016年06月23日
  • 标签: iOS
  • 封装AFN3.1并且封装自定义alertView

好久没写博客了,最近项目接近上线,加班也多了,把最近更新的afn封装了下,同时封装的还有一个自定义的提示框。简单的利用一个写好的框架。

  • 一、封装AFN

  • AFN3.1里更新了很多东西,这里只封装了一下如何上传图片并且返回进度条
  • 首先,我们需要定义三个block,用来把进度,成功后返回的数据和失败返回的error

    1
    2
    3
    4
    5
    6
    7
    8
    
      /**定义请求成功的block*/
      typedef void(^requestSuccess)( NSDictionary * responseObject);
        
      /**定义请求失败的block*/
      typedef void(^requestFailure)( NSError *error);
        
      /**定义上传进度block*/
      typedef void(^uploadProgress)(CGFloat progress);
    
  • 接着导入AFNetworking.h,并且写方法名字。这里,因为上传图片的时候有图片类型,图片名字,文件名字等,并且有可能上传多张图片,所以我们在封装的时候要把所有的问题都考虑进去,因此,封装以及参数如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
      /**
      *  上传图片
      *
      *  @param baseUrlStr   baseUrlStr
      *  @param appendUrlStr appendUrlStr
      *  @param para         参数
      *  @param imageArray   图片数组
      *  @param successBlock 成功block
      *  @param failureBlock 失败block
      *  @param progress     上传进度
      */
      +(void)UPDATA_baseUrlStr:(NSURL *)baseUrl
              appendUrlStr:(NSString *)appendUrlStr
                  parameters:(NSDictionary *)para
              withImageArr:(NSArray *)imageArray
                  sourceName:(NSArray *)nameArr
                  fileName:(NSArray *)fileNameArr
                  mimeType:(NSString *)type
          withSuccessBlock:(requestSuccess)successBlock
              withFailurBlock:(requestFailure)failureBlock
          withUpLoadProgress:(uploadProgress)progressUp;
    
  • 接着在.m里实现方法如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    
      /**
       *  上传图片
       *
       *  @param baseUrlStr   baseUrlStr
       *  @param appendUrlStr appendUrlStr
       *  @param para         参数
       *  @param imageArray   图片数组
       *  @param successBlock 成功block
       *  @param failureBlock 失败block
       *  @param progressUp   上传进度
       */
      +(void)UPDATA_baseUrlStr:(NSURL *)baseUrl
                  appendUrlStr:(NSString *)appendUrlStr
                    parameters:(NSDictionary *)para
                  withImageArr:(NSArray *)imageArray
                    sourceName:(NSArray *)nameArr
                      fileName:(NSArray *)fileNameArr
                      mimeType:(NSString *)type
              withSuccessBlock:(requestSuccess)successBlock
               withFailurBlock:(requestFailure)failureBlock
            withUpLoadProgress:(uploadProgress)progressUp
      {
          NSMutableArray *tempSourceNameArr = [NSMutableArray array];
          NSMutableArray *tempFileNameArr = [NSMutableArray array];
          if (nameArr.count > 0) {
              [tempSourceNameArr addObjectsFromArray:nameArr];
          }else {
              for (int i = 0; i < imageArray.count; i ++) {
                  [tempSourceNameArr addObject: [NSString stringWithFormat:@"name%d",i]];
              }
          }
            
          if (fileNameArr.count > 0) {
              [tempFileNameArr addObjectsFromArray:fileNameArr];
          }else {
              for (int i = 0; i < imageArray.count; i ++) {
                  [tempFileNameArr addObject: [NSString stringWithFormat:@"image%d",i]];
              }
          }
            
          AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithBaseURL:baseUrl];
          manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",@"text/plain",nil];
          NSString *mimeTypeStr = [NSString stringWithFormat:@"image/%@",type];
            
          [manager POST:appendUrlStr parameters:para constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
              int j = 0;
              for (UIImage *image in imageArray) {
                  NSData *imgData;
                  if ([type isEqualToString:@"jpg"]) {
                      imgData = UIImageJPEGRepresentation(image, 0.5);
                  } else
                  {
                      imgData = UIImagePNGRepresentation(image);
                  }
                  [formData appendPartWithFileData:imgData name:[tempSourceNameArr objectAtIndex:j] fileName:[tempFileNameArr objectAtIndex:j] mimeType:mimeTypeStr];
                  j++;
              }
          } progress:^(NSProgress * _Nonnull uploadProgress) {
      //        NSLog(@"......fractionCompleted:%f",uploadProgress.fractionCompleted);
      //        NSLog(@"......completedUnitCount:%lld",uploadProgress.completedUnitCount);
      //        NSLog(@"......totalUnitCount:%lld",uploadProgress.totalUnitCount);
                
              if (uploadProgress.totalUnitCount != 0.00) {
                  CGFloat progress = uploadProgress.completedUnitCount/(CGFloat)uploadProgress.totalUnitCount;
                  progressUp(progress);
              }
                
          } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
              successBlock(responseObject);
          } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
              failureBlock(error);
          }];
          
      }
    
  • 需要注意的是,在progress上传进度的传回来的进度里,传回来的是一个NSProgress类,点击去可以看到,这个类里有一个属性,叫fractionCompleted,这个属性是double型的。然而,问题来了,当我们打印这个属性的时候发现,这个属性会先传过来1,然后再传过来0.12、0.23等等浮点型的进度条。那我们没有办法了嘛?当然不是。参考属性我们可以看到,NSProgress里还有两个属性:uploadProgress.completedUnitCount和uploadProgress.totalUnitCount。前者是已经上传的资源总数,后者是所上传的资源的总字节数。通过两者相处,可以得出进度条的百分比。因此,可以通过progress把两者的商传出去。

    1
    2
    
      CGFloat progress = uploadProgress.completedUnitCount/(CGFloat)uploadProgress.totalUnitCount;
      progressUp(progress);
    

这样,就可以得到上传进度了。

  • AFN封装就这样完成了。

  • 二、封装提示框

  • 首先是github上的一个还不错的库,我稍微改动了一下,把“取消”和“确定”按钮都传了出去,为了修改背景色,文字颜色等。

    1
    
      typedef void(^LXAlertClickIndexBlock)(NSInteger clickIndex,UIButton *cancelBtn,UIButton *otherBtn);
    
  • 然后我们要定义一下动画类型,类型为枚举类型:

    1
    2
    3
    4
    5
    6
    
      typedef NS_ENUM(NSInteger , LXAShowAnimationStyle) {
          LXASAnimationDefault    = 0,
          LXASAnimationLeftShake  ,
          LXASAnimationTopShake   ,
          LXASAnimationNO         ,
      };
    
  • 接着我们写方法.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    
      @property (nonatomic,copy)LXAlertClickIndexBlock clickBlock;
        
      @property (nonatomic,assign)LXAShowAnimationStyle animationStyle;
    
    
      /**
       *  初始化alert方法(根据内容自适应大小,目前只支持1个按钮或2个按钮)
       *
       *  @param title         标题
       *  @param titleColor    标题颜色
       *  @param message       内容(根据内容自适应大小)
       *  @param messageColor  内容颜色
       *  @param cancelTitle   取消按钮
       *  @param otherBtnTitle 其他按钮
       *  @param block         点击事件block
       *
       *  @return 返回alert对象
       */
      -(instancetype)initWithTitle:(NSString *)title
                        titleColor:(UIColor *)titleColor
                           message:(NSString *)message
                      messageColor:(UIColor *)messageColor
                    cancelBtnTitle:(NSString *)cancelTitle
                     otherBtnTitle:(NSString *)otherBtnTitle
                   clickIndexBlock:(LXAlertClickIndexBlock)block;
        
      /**
       *  showLXAlertView
       */
      -(void)showLXAlertView;
        
      /**
       *  不隐藏,默认为NO。设置为YES时点击按钮alertView不会消失(适合在强制升级时使用)
       */
      @property (nonatomic,assign)BOOL dontDissmiss;
    
  • 这里我们又搞出一个clickBlock,是为了捕捉按钮的点击事件。方法实现如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    
      -(instancetype)initWithTitle:(NSString *)title
                        titleColor:(UIColor *)titleColor
                           message:(NSString *)message
                      messageColor:(UIColor *)messageColor
                    cancelBtnTitle:(NSString *)cancelTitle
                     otherBtnTitle:(NSString *)otherBtnTitle
                   clickIndexBlock:(LXAlertClickIndexBlock)block
      {
          if(self=[super init]){
              self.frame=MainScreenRect;
              self.backgroundColor=[UIColor colorWithWhite:.3 alpha:.7];
                
              _alertView=[[UIView alloc] init];
              _alertView.backgroundColor=[UIColor whiteColor];
              _alertView.layer.cornerRadius=6.0;
              _alertView.layer.masksToBounds=YES;
              _alertView.userInteractionEnabled=YES;
                
                
              if (title) {
                  _titleLab=[[UILabel alloc] initWithFrame:CGRectMake(0, 10, AlertView_W, LXATitle_H)];
                  _titleLab.text=title;
                  _titleLab.textAlignment=NSTextAlignmentCenter;
                  _titleLab.font=LXADTitleFont;
        
                  if (titleColor) {
                      _titleLab.textColor=titleColor;
                  }else{
                      _titleLab.textColor=[UIColor blackColor];
                  }
              }
                
              CGFloat messageLabSpace = 25;
              _messageLab=[[UILabel alloc] init];
              _messageLab.backgroundColor=[UIColor whiteColor];
              _messageLab.text=message;
              if (messageColor) {
                  _messageLab.textColor=messageColor;
              }else{
                  _messageLab.textColor=[UIColor lightGrayColor];
              }
              _messageLab.font=LXADMessageFont;
              _messageLab.numberOfLines=0;
              _messageLab.textAlignment=NSTextAlignmentCenter;
              _messageLab.lineBreakMode=NSLineBreakByTruncatingTail;
              _messageLab.characterSpace=2;
              _messageLab.lineSpace=3;
              CGSize labSize = [_messageLab getLableRectWithMaxWidth:AlertView_W-messageLabSpace*2];
              CGFloat messageLabAotuH = labSize.height < MessageMin_H?MessageMin_H:labSize.height;
              CGFloat endMessageLabH = messageLabAotuH > MessageMAX_H?MessageMAX_H:messageLabAotuH;
              _messageLab.frame=CGRectMake(messageLabSpace, _titleLab.frame.size.height+_titleLab.frame.origin.y+10, AlertView_W-messageLabSpace*2, endMessageLabH);
                
                
              //计算_alertView的高度
              _alertView.frame=CGRectMake(0, 0, AlertView_W, _messageLab.frame.size.height+LXATitle_H+LXABtn_H+40);
              _alertView.center=self.center;
              [self addSubview:_alertView];
              [_alertView addSubview:_titleLab];
              [_alertView addSubview:_messageLab];
                
              if (cancelTitle) {
                  _cancelBtn=[UIButton buttonWithType:UIButtonTypeCustom];
                  [_cancelBtn setTitle:cancelTitle forState:UIControlStateNormal];
                  [_cancelBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
                  [_cancelBtn setBackgroundImage:[UIImage imageWithColor:SFQLightGrayColor] forState:UIControlStateNormal];
                  _cancelBtn.titleLabel.font=LXADBtnTitleFont;
                  _cancelBtn.layer.cornerRadius=3;
                  _cancelBtn.layer.masksToBounds=YES;
                  [_cancelBtn addTarget:self action:@selector(YBAlerBtnClick:) forControlEvents:UIControlEventTouchUpInside];
                  [_alertView addSubview:_cancelBtn];
              }
                
              if (otherBtnTitle) {
                  _otherBtn=[UIButton buttonWithType:UIButtonTypeCustom];
                  [_otherBtn setTitle:otherBtnTitle forState:UIControlStateNormal];
                  [_otherBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
                  _otherBtn.titleLabel.font=LXADBtnTitleFont;
                  _otherBtn.layer.cornerRadius=3;
                  _otherBtn.layer.masksToBounds=YES;
                  [_otherBtn setBackgroundImage:[UIImage imageWithColor:SFQMainColor] forState:UIControlStateNormal];
                  [_otherBtn addTarget:self action:@selector(YBAlerBtnClick:) forControlEvents:UIControlEventTouchUpInside];
                  [_alertView addSubview:_otherBtn];
              }
                
              CGFloat btnLeftSpace = 40;//btn到左边距
              CGFloat btn_y = _alertView.frame.size.height-40;
              if (cancelTitle && !otherBtnTitle) {
                  _cancelBtn.tag=0;
                  _cancelBtn.frame=CGRectMake(btnLeftSpace, btn_y, AlertView_W-btnLeftSpace*2, LXABtn_H);
              }else if (!cancelTitle && otherBtnTitle){
                  _otherBtn.tag=0;
                  _otherBtn.frame=CGRectMake(btnLeftSpace, btn_y, AlertView_W-btnLeftSpace*2, LXABtn_H);
              }else if (cancelTitle && otherBtnTitle){
                  _cancelBtn.tag=0;
                  _otherBtn.tag=1;
                  CGFloat btnSpace = 20;//两个btn之间的间距
                  CGFloat btn_w =(AlertView_W-btnLeftSpace*2-btnSpace)/2;
                  _cancelBtn.frame=CGRectMake(btnLeftSpace, btn_y, btn_w, LXABtn_H);
                  _otherBtn.frame=CGRectMake(_alertView.frame.size.width-btn_w-btnLeftSpace, btn_y, btn_w, LXABtn_H);
              }
                
              block(1111111,_cancelBtn,_otherBtn);
              self.clickBlock=block;
                
          }
          return self;
      }
        
        
      -(void)YBAlerBtnClick:(UIButton *)btn{
            
          if (self.clickBlock) {
              self.clickBlock(btn.tag,nil,nil);
          }
            
          if (!_dontDissmiss) {
              [self dismissAlertView];
          }
            
      }
        
      -(void)setDontDissmiss:(BOOL)dontDissmiss{
          _dontDissmiss=dontDissmiss;
      }
        
      -(void)showLXAlertView{
            
            
            
          _alertWindow=[[UIWindow alloc] initWithFrame:MainScreenRect];
          _alertWindow.windowLevel=UIWindowLevelAlert;
          [_alertWindow becomeKeyWindow];
          [_alertWindow makeKeyAndVisible];
            
          [_alertWindow addSubview:self];
            
          [self setShowAnimation];
            
      }
        
      -(void)dismissAlertView{
          [self removeFromSuperview];
          [_alertWindow resignKeyWindow];
      }
        
      -(void)setShowAnimation{
            
          switch (_animationStyle) {
                    
              case LXASAnimationDefault:
              {
                  [UIView animateWithDuration:0 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
                      [_alertView.layer setValue:@(0) forKeyPath:@"transform.scale"];
                  } completion:^(BOOL finished) {
                      [UIView animateWithDuration:0.23 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
                          [_alertView.layer setValue:@(1.2) forKeyPath:@"transform.scale"];
                      } completion:^(BOOL finished) {
                          [UIView animateWithDuration:0.09 delay:0.02 options:UIViewAnimationOptionCurveEaseInOut animations:^{
                              [_alertView.layer setValue:@(.9) forKeyPath:@"transform.scale"];
                          } completion:^(BOOL finished) {
                              [UIView animateWithDuration:0.05 delay:0.02 options:UIViewAnimationOptionCurveEaseInOut animations:^{
                                  [_alertView.layer setValue:@(1.0) forKeyPath:@"transform.scale"];
                              } completion:^(BOOL finished) {
                                    
                              }];
                          }];
                      }];
                  }];
              }
                  break;
                    
              case LXASAnimationLeftShake:{
            
                  CGPoint startPoint = CGPointMake(-AlertView_W, self.center.y);
                  _alertView.layer.position=startPoint;
                    
                  //damping:阻尼,范围0-1,阻尼越接近于0,弹性效果越明显
                  //velocity:弹性复位的速度
                  [UIView animateWithDuration:.8 delay:0 usingSpringWithDamping:.5 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
                      _alertView.layer.position=self.center;
                        
                  } completion:^(BOOL finished) {
                        
                  }];
              }
                  break;
                    
              case LXASAnimationTopShake:{
                    
                  CGPoint startPoint = CGPointMake(self.center.x, -_alertView.frame.size.height);
                  _alertView.layer.position=startPoint;
                    
                  //damping:阻尼,范围0-1,阻尼越接近于0,弹性效果越明显
                  //velocity:弹性复位的速度
                  [UIView animateWithDuration:.8 delay:0 usingSpringWithDamping:.5 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
                      _alertView.layer.position=self.center;
                        
                  } completion:^(BOOL finished) {
                        
                  }];
              }
                  break;
                    
              case LXASAnimationNO:{
                    
              }
                    
                  break;
                    
              default:
                  break;
          }
            
      }
        
        
      -(void)setAnimationStyle:(LXAShowAnimationStyle)animationStyle{
          _animationStyle=animationStyle;
      }
        
      @end
        
        
        
        
        
      @implementation UIImage (Colorful)
        
      + (UIImage *)imageWithColor:(UIColor *)color
      {
          CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
          UIGraphicsBeginImageContext(rect.size);
          CGContextRef context = UIGraphicsGetCurrentContext();
            
          CGContextSetFillColorWithColor(context, [color CGColor]);
          CGContextFillRect(context, rect);
            
          UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
          UIGraphicsEndImageContext();
            
          return image;
      }
    
  • 完成上一步以后,把它封装在YBAFN.h里;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    
      /**
       *  自定义提醒
       *
       *  @param str   提醒文字
       *  @param style 动画风格
       */
      +(void)YB_alertViewWithShowStr:(NSString *)str withStyle:(LXAShowAnimationStyle)style
      {
          LXAlertView *alert = [[LXAlertView alloc] initWithTitle:@"提示" titleColor:[UIColor blackColor] message:str messageColor:[UIColor grayColor] cancelBtnTitle:nil otherBtnTitle:@"确定" clickIndexBlock:^(NSInteger clickIndex, UIButton *cancelBtn, UIButton *otherBtn) {
          }];
          if (!style) {
              style = LXASAnimationTopShake;
          }
          alert.animationStyle=style;
          [alert showLXAlertView];
      }
        
        
      + (LXAlertView *)YB_alertViewContent:(NSString *)showStr WithStyle:(LXAShowAnimationStyle)style indexBlock:(void (^)(NSInteger btnIndex))indexBlock
      {
          LXAlertView *alert = [[LXAlertView alloc] initWithTitle:@"提示" titleColor:[UIColor blackColor] message:showStr messageColor:[UIColor grayColor] cancelBtnTitle:nil otherBtnTitle:@"确定" clickIndexBlock:^(NSInteger clickIndex, UIButton *cancelBtn, UIButton *otherBtn) {
                
          }];
          alert.clickBlock = ^(NSInteger clickIndex,UIButton *cancelBtn,UIButton *otherBtn){
              indexBlock(clickIndex);
          };
          alert.animationStyle=style;
          [alert showLXAlertView];
          return alert;
      }
    
  • 在程序中调用:

    1
    2
    3
    4
    5
    
      [YBAFN YB_alertViewContent:@"这是用来测试的呀" WithStyle:LXASAnimationLeftShake indexBlock:^(NSInteger btnIndex) {
              if (btnIndex == 0) {
                  NSLog(@"点击了确定");
              }
          }];
    
  • 动图如下:

效果图

  • 至此,大功告成。项目照例放在此:DEMO