打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
UISlider添加单击事件
原生UISlider用作进度条时没有提供单击事件的接口,通过继承在子类中实现单击事件又有杀鸡用牛刀的感觉,于是考虑在Category中实现。
创建UISlider+touch.h和UISlider+touch.m文件,添加单击事件方法:
  1. @interface UISlider (touch)
  2. // 单击手势
  3. - (void)addTapGestureWithTarget: (id)target
  4.                          action: (SEL)action;
  5. @end
复制代码

实现原理是为UISlider对象添加UITapGestureRecognizer,当触发tap事件时利用传入的target和action回调单击事件。

--------------------------------------------------------------------------------

在Category添加方法很简单,但是要扩展属性以保存传入的target和action两个参数就需要利用associative机制了(‘associative’机制参考文章)。使用它我们要在.m文件中引入#import <objc/runtime.h>

这里我们主要用到以下两个方法:

  1. objc_setAssociatedObject:

  2. // 添加扩展属性
  3. void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy)  
  4. objc_getAssociatedObject

  5. // 获取扩展属性
  6. id objc_getAssociatedObject(id object, void *key)
复制代码

通过objc_setAssociatedObject方法我们可以为UISlider扩展两个属性来接收传入的target和action。

通过objc_getAssociatedObject方法就可以在接收到UITapGestureRecognizer单击手势时获取target和action,利用[target performSelector:action withObject:self]方法实现单击事件的回调。
--------------------------------------------------------------------------------

下面看下.m中的具体实现:

addTapGestureWithTarget方法为UISlider对象添加UITapGestureRecognizer手势,并为它扩展了三个属性。
  1. static char *gestureKey;
  2. static char *targetKey;
  3. static char *actionStringKey;
  4. @implementation UISlider (touch)
  5. - (void)addTapGestureWithTarget: (id)target action: (SEL)action
  6. {
  7.      id gesture =  objc_getAssociatedObject(self, &gestureKey);
  8.     if (!gesture) {
  9.          objc_setAssociatedObject(self, &targetKey, target, OBJC_ASSOCIATION_ASSIGN);
  10.          objc_setAssociatedObject(self, &actionStringKey, NSStringFromSelector(action), OBJC_ASSOCIATION_RETAIN);
  11.          UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action: @selector(tap:)];
  12. tap.numberOfTapsRequired = 1;
  13.         tap.numberOfTouchesRequired = 1;
  14.         [self addGestureRecognizer:tap];
  15.        objc_setAssociatedObject(self, &gestureKey, tap, OBJC_ASSOCIATION_RETAIN);
  16.    }
  17. }
复制代码

tap:方法中根据点击的位置更新UISlider对象的value,同时从扩展属性中获取target和action回调单击事件。
  1. - (void)tap: (UITapGestureRecognizer *)sender
  2. {
  3.      if (sender.state == UIGestureRecognizerStateEnded) {
  4.          CGPoint location = [sender locationInView:self];
  5.          float x = location.x;
  6.          float r = x/self.frame.size.width;
  7.          float value = (self.maximumValue-self.minimumValue) * r;
  8.          [self setValue:value animated:YES];
  9.        id target = objc_getAssociatedObject(self, &targetKey);
  10.         if (target) {
  11.             NSString *actionStr = objc_getAssociatedObject(self, &actionStringKey);
  12.             SEL action  = NSSelectorFromString(actionStr);
  13.             [target performSelector:action withObject:self];
  14.        }
  15.     }
  16. }
复制代码

dealloc方法中移除UITapGestureRecognizer

  1. - (void)dealloc
  2. {
  3.      UITapGestureRecognizer *tap;
  4.      id gesture =  objc_getAssociatedObject(self, &gestureKey);
  5.      if (gesture) {
  6.          tap = (UITapGestureRecognizer*)gesture;
  7.          [self removeGestureRecognizer:tap];
  8.      }
  9. }
  10.   @end
复制代码

--------------------------------------------------------------------------------


这样我们为UISlider添加单击事件,只需要将Category文件拷入项目import引入就OK了。

原文链接:http://www.cocoachina.com/bbs/read.php?tid=145660&fpage=3

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
iOS:学习runtime的理解和心得
iOS学习系列
Associated Objects
iOS动态性(一):动态添加属性的方法——关联(e.g. 向Category添加成员变量)
Associated Objects | Esoft Mobile
iOS动态性(四) 1行代码实现iOS序列化与反序列化(runtime)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服