WCBlock 让你的编码更简单

WCBlock 使你的代码更加简单:

https://github.com/manakiaHk/WCBlock
一个轻量级的UIKit Extension Block库
它为NotificationCenter、KVO、Target-action、GestureRecognizer、UIView、UIButton、UITextField等的事件响应提供了很友好的block回调支持。提高代码的聚合度,使编码更加轻松,提高开发效率。

相信大家对iOS开发都已经非常娴熟,然而你或许还是在对自己无时无刻都在写相同的代码而感到枯燥乏味,你或许考虑过自己实现一套方法把自己从中解放出来。当然,你或许对你每天所面临的枯燥已经抱着无所谓的心态,我想你大概已经习惯如此。但是不管怎么样,解放是人类的天性,这点我们得承认。

我们一起来回顾一下你上周写过的一些代码:

比如:

1. 一个UIView 、UIImageView 对象的点击,我猜你大概是这样写的:


- (void)aMethod {
 UIView *view = [[UIView alloc]init];
    UITapGestureRecognizer *viewTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(viewTaped:)];
    [view addGestureRecognizer:viewTap];
    
    UIImageView *imageView = [[UIImageView alloc]init];
    UITapGestureRecognizer *imgTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(viewTaped:)];
    imageView.userInteractionEnabled = YES;
    [imageView addGestureRecognizer:imgTap];
}
- (void)viewTaped:(UIGestureRecognizer*)ges {
    // your code...
}

2. 一个按钮的点击,你大概这样写的:

- (void)aMethod {
   UIButton *button0 = [[UIButton alloc]init];
    [button0 addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)buttonClicked:(id)sender {
    // your code...
}

3. 一个文本输入框的监听,你大概是这样写的:

///你首先要遵守协议
@interface YourClass ()<UITextFieldDelegate>
@end
-----------
- (void)aMethod {
   UITextField *textf = [[UITextField alloc]init];
    textf.delegate = self;/// 你要设置代理
}
///你最后还要实现代理的协议
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
         // your code...
       return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
        // your code...
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
      // your code...
      return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{   
       // your code...
      return YES;
    
}

或者 你这样写的:

- (void)aMethod {
    UITextField *textf = [[UITextField alloc]init];
    [textf addTarget:self action:@selector(textFieldChanged:) forControlEvents:UIControlEventEditingChanged];
}
- (void)textFieldChanged:(UITextField*)textField{
    // your code...
}

4. 再来看看你的KVO

- (void)aMethod {
    [_anObject addObserver:self forKeyPath:@"keyPath0" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
    [_anObject addObserver:self forKeyPath:@"keyPath1" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
    [_anObject addObserver:self forKeyPath:@"keyPath2" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey> *)change context:(void *)context {
       // your code...
}
- (void)dealloc {
    [_anObject removeObserver:self forKeyPath:@"keyPath0"];
    [_anObject removeObserver:self forKeyPath:@"keyPath1"];
    [_anObject removeObserver:self forKeyPath:@"keyPath2"];
}

5. 你一般大概都这样使用通知中心的:

- (void)aMethod {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(noteReceived:)  name:kNoteName object:nil];

/*
 _observer = [[NSNotificationCenter defaultCenter] addObserverForName:kNoteName object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        // your code
    }];
*/
}
- (void)noteReceived:(NSNotification*)note {
    // your code ...
}
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kNoteName object:nil];

/*
  if (_observer) {
        [[NSNotificationCenter defaultCenter] removeObserver:_observer name:kNoteName object:nil];
    }
*/
}

6. 再比如一个简单的弹框提示:


@interface YourClass ()<UIAlertViewDelegate>
@end
---------
- (void)aMethod {
     UIAlertView *alert = [[UIAlertView alloc]init];
    alert.delegate = self;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    // your code
}

5. 再比如有这样一个场景:在2个以上的方法中同时监听一个按钮的点击或者一个文本框的输入或者一个键值观察,你可能会停下来好好想想怎么去实现。

还有很多以上类似的应用场景 ,我相信你写这些代码的时候都恨不得编译器能清楚的知道你的用意并且为你自动填充这些重复的代码。节约下来的时间足够你喝一杯的咖啡来养养神。

接下来看看WCBlock 能为你做些什么

1 .控件的交互事件回调

    [view wc_bindViewTapBlockNext:^(UIView *view, WCViewTap *tap) {
         // your code...
    }];

   imageView.userInteractionEnabled = YES;//对于imageView 的userInteractionEnabled 属性保留apple api的做法,你需要主动设置为YES
   [imageView wc_bindViewTapBlockNext:^(UIView *view, WCViewTap *tap) {
        // your code...
    }];

    ///你可以通过返回值设置属性以及代理 这点和Apple的api完全一样 ,比如:
   WCViewTap *tap =   [view wc_bindViewTapBlockNext:^(UIView *view, WCViewTap *tap) {
         // your code...
    }];
    tap.numberOfTapsRequired = 2;
    tap.delegate = self;
    
    ///你还可以为view绑定其他的手势block回调。e.g:
    [view wc_bindViewPanBlockNext:^(UIView *view, WCViewPan *pan) {
        // your code...
    }];
    [view wc_bindViewLongPressBlockNext:^(UIView *view, WCViewLongPress *longPress) {
         // your code...
    }];
    [view wc_bindViewRotationBlockNext:^(UIView *view, WCViewRotation *rotation) {
      //  NSLog(@"%0.2f",rotation.rotation);//旋转角度
       // NSLog(@"%0.2f",rotation.velocity);//旋转速度
    }];

2. 手势回调

 UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]init];
    [tapGes wc_bindGestureBlockNext:^(UIGestureRecognizer *sender) {
        //...
    }];
    
    UISwipeGestureRecognizer *swipeGesture =  [[UISwipeGestureRecognizer alloc]init];
    [swipeGesture wc_bindGestureBlockNext:^(UIGestureRecognizer *sender) {
        //...
    }];
    
    UIRotationGestureRecognizer *rotationGesture =  [[UIRotationGestureRecognizer alloc]init];
    [rotationGesture wc_bindGestureBlockNext:^(UIGestureRecognizer *sender) {
        //...
    }];
    
    UIPanGestureRecognizer *panGesture =  [[UIPanGestureRecognizer alloc]init];
    [panGesture wc_bindGestureBlockNext:^(UIGestureRecognizer *sender) {
        //...
    }];

3. button、segmentedControl、 slider and so on. e.g:

 UIButton *button = [[UIButton alloc]initWithFrame:btnFrame];
    [button wc_bindForControlEvents:UIControlEventTouchUpInside blockNext:^(id sender) {
        //button clicked...
    }];
    
    UISegmentedControl *segment = [[UISegmentedControl alloc]initWithItems:@[@"title0",@"title1",@"title2"]];
    [segment wc_bindSegmentControlValueChangedBlockNext:^(NSInteger selectedIndex) {
       // NSLog(@"segment selected index %ld",selectedIndex);
    }];
    
    //tip: 和以往一样,当wcblock 捕获了外部变量,可能将导致循环引用 ,你需要用 __weak 避免这样事情发生  
   
    UISlider *slider = [[UISlider alloc]initWithFrame:sliderFrame];
    __weak typeof(self) weakSelf = self;
    [slider wc_bindSliderValueChangedBlockNext:^(CGFloat value) {
        __strong typeof(weakSelf) self = weakSelf;
       [self sendAMesseage];
    }];
    
    UIAlertView *alerView = [[UIAlertView alloc]initWithTitle:@"title" message:@"message" delegate:nil    cancelButtonTitle:@"cancle" otherButtonTitles:@"ok", nil];
    [alerView wc_bindAlertButtonClickedBlockNext:^(NSInteger index) {
       // NSLog(@"clicked index: %ld",index);
    }];
    [alerView show];

4. 文本输入框 textField

 UITextField *textfiled = [[UITextField alloc]initWithFrame:textFieldframe];
    [textfiled wc_bindTextFieldEditingChangedBlockNext:^(UITextField *textField, NSString *value) {
        //NSLog(@"textfiled text:%@",value);
    }];
    [textfiled wc_bindTextFieldShouldChangeCharactersHandlerBlock:^BOOL(UITextField *textField, NSRange shouldChangeCharactersInRange, NSString *replacementString) {
        return YES;
    }];
    [textfiled wc_bindTextFieldEditingDidBeginBlockNext:^(UITextField *textField) {
       //textfiled did begin editing...
     }];
    [textfiled wc_bindTextFieldEditingDidEndBlockNext:^(UITextField *textField) {
        //textfiled did end editing... 
    }];

5. 通知, WCBlock 将自动为你管理移除通知中心的observer对象

 [WCNotificationCenter wc_addObserverForName:kNoteName object:nil contextObj:self blockNext:^(NSNotification * _Nullable note) {
      //..
  }];
  
//异步通知用
 [WCNotificationCenter wc_addObserverForName:kNoteName object:nil contextObj:self queue: [NSOperationQueue mainQueue] blockNext:^(NSNotification * _Nullable note) {
        //..
 }];

6. KVO

[_anObject wc_addObserverForKeyPath:@"keyPath0" valueBlockNext:^(NSString *keypath, id ofObj, id oldValue, id newValue) {
      //..
  }];
  [_anObject wc_addObserverForKeyPaths:@[@"keyPath1",@"keyPath2"] valueBlockNext:^(NSString *keypath, id ofObj, id oldValue, id newValue) {
      if ([keypath isEqualToString:@"keyPath1"]) {
          //..
      }else if([keypath isEqualToString:@"keyPath2"]){
          //..
      }else;
  }];
   [_anObject wc_addObserverForKeyPath:@"keyPath3" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld changeBlockNext:^(NSString *keypath, id ofObj, NSDictionary<NSKeyValueChangeKey> *change) {
      //..
  }];

和Apple api 一样 对于KVO 你需要自己移除键值观察, 像这样:

 - (void)dealloc {
   [_anObject wc_removeObserverForKeyPath:@"keyPath0"];
   [_anObject wc_removeObserverForKeyPath:@"keyPath1"];
   [_anObject wc_removeObserverForKeyPaths:@[@"keyPath2",@"keyPath3"]];
}

你可以为每个对象绑定多个同样类型的block ,每个block都会调用 ,因为不排除你会在多个地方同时使用,所以你要知道WCBlock是可以做到这点的。 但是记住 handerBlock 除外,它只能绑定一个,因为你并不希望多个hander同时操作同一个对象,所以对于同一个对象 绑定多个同样类型的handler block ,这时候只有最后一个有效。e.g: 像下面的每个block都将调用

    [view wc_bindViewTapBlockNext:^(UIView *view, WCViewTap *tap) {
        NSLog(@"0--view taped");
    }];
    [view wc_bindViewTapBlockNext:^(UIView *view, WCViewTap *tap) {
        NSLog(@"1--view taped");
    }];
    [view wc_bindViewTapBlockNext:^(UIView *view, WCViewTap *tap) {
        NSLog(@"2--view taped");
    }];
    
    [textfiled wc_bindTextFieldEditingChangedBlockNext:^(UITextField *textField, NSString *value) {
        NSLog(@"0--textfiled text:%@",value);
    }];
    [textfiled wc_bindTextFieldEditingChangedBlockNext:^(UITextField *textField, NSString *value) {
        NSLog(@"1--textfiled text:%@",value);
    }];
    [textfiled wc_bindTextFieldEditingChangedBlockNext:^(UITextField *textField, NSString *value) {
        NSLog(@"2--textfiled text:%@",value);
    }];
像下面的 block 只有最后一个有效(请注意,它们是 HandlerBlock)

 [textfiled wc_bindTextFieldShouldChangeCharactersHandlerBlock:^BOOL(UITextField *textField, NSRange shouldChangeCharactersInRange, NSString *replacementString) {
        if ([replacementString containsString:@"a"]) {
            return NO;
        }
        return YES;
    }];
    [textfiled wc_bindTextFieldShouldChangeCharactersHandlerBlock:^BOOL(UITextField *textField, NSRange shouldChangeCharactersInRange, NSString *replacementString) {
        if ([replacementString containsString:@"b"]) {
            return NO;
        }
        return YES;
    }];
    [textfiled wc_bindTextFieldShouldChangeCharactersHandlerBlock:^BOOL(UITextField *textField, NSRange shouldChangeCharactersInRange, NSString *replacementString) {
        if ([replacementString containsString:@"c"]) {
            return NO;
        }
        return YES;
    }];

本文的介绍就结束了,感谢你的阅读。
祝你开心
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容