UIControl是App开发中每天都需要使用,每一个IOS开发者对于UIControl都是无比熟悉的,UIButton、UISlider、UISwitch等等。
而我们使用这些控件的主要方式就是通过UIControl提供给我们的`Control Event`
```
enum {
UIControlEventTouchDown = 1 << 0,
UIControlEventTouchDownRepeat = 1 << 1,
UIControlEventTouchDragInside = 1 << 2,
UIControlEventTouchDragOutside = 1 << 3,
UIControlEventTouchDragEnter = 1 << 4,
UIControlEventTouchDragExit = 1 << 5,
UIControlEventTouchUpInside = 1 << 6,
UIControlEventTouchUpOutside = 1 << 7,
UIControlEventTouchCancel = 1 << 8,
UIControlEventValueChanged = 1 << 12,
UIControlEventEditingDidBegin = 1 << 16,
UIControlEventEditingChanged = 1 << 17,
UIControlEventEditingDidEnd = 1 << 18,
UIControlEventEditingDidEndOnExit = 1 << 19,
UIControlEventAllTouchEvents = 0x00000FFF,
UIControlEventAllEditingEvents = 0x000F0000,
UIControlEventApplicationReserved = 0x0F000000,
UIControlEventSystemReserved = 0xF0000000,
UIControlEventAllEvents = 0xFFFFFFFF
};
```
这些control event对于我们来说也不太陌生,正是由这些简单的event拼凑成了我们应用的交互。
不过这里面却是有一个小秘密。
##小秘密——70像素
小秘密是什么呢?
如果你用过`UIControlEventTouchDragExit`
并且你对于`UIControlEventTouchDragExit`的触摸时机较为敏感的话,你就会发现如果手指离开我们的Control的bounds的那一刻,`UIControlEventTouchDragExit`并没有被触发?
可是苹果的文档写写相当清楚,当手指离开了bounds的时候就应该触发。
```
UIControlEventTouchDragExit
An event where a finger is dragged from within a control to outside its bounds.
Available in iOS 2.0 and later.
Declared in UIControl.h.
```
事实是检验真理的唯一标准?
所以我试着输出了一下`UIControlEventTouchDragExit`被触发时候touch的坐标。
结果就是`70像素左右`,每次触发时候的位置都是距离control的边界70像素左右
可能文字描述的不够形象。放张图
图中的红色边框就是一个按钮的bounds
而图中的绿色边框就是事件触发时候的区域边界
当手指越过绿色边框的时候,事件就被触发了
而红色边框和绿色边框之间的距离是`70像素`
那是不是其他的contrl event是不是符合这个规律呢?
我做了简单的测试,发现是的
`UIControlEventTouchDragInside`、`UIControlEventTouchDragOutside`等等的触发边界都是70像素左右。
##自定义触发边界
不得不说,有时候这多出来的70像素是相当的讨厌的,因为我们不需要,那么我们是否能够去自定义呢?
答案当然是肯定的。
还是以`UIControlEventTouchDragExit`为例吧,让我们来修改`UIControlEventTouchDragExit`的触发边界
贴出一段代码
```
- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
// 设置新的边界
CGFloat boundsExtension = 25.0f;
CGRect outerBounds = CGRectInset(self.bounds, -1 * boundsExtension, -1 * boundsExtension);
// 判断触摸位置
BOOL touchOutside = !CGRectContainsPoint(outerBounds, [touch locationInView:self]);
if(touchOutside)
{
// 判断是UIControlEventTouchDragExit/UIControlEventTouchDragOutside
BOOL previousTouchInside = CGRectContainsPoint(outerBounds, [touch previousLocationInView:self]);
if(previousTouchInside)
{
[self sendActionsForControlEvents:UIControlEventTouchDragExit];
}
else
{
[self sendActionsForControlEvents:UIControlEventTouchDragOutside];
}
}
// 如果不是想要修改的control event,返回原操作
return [super continueTrackingWithTouch:touch withEvent:event];
}
```
##感想
虽然自己也每天使用UIControl,不过也是现在才发现这个有趣的现象,IOS中还是有很多东西需要探索,每日自省自勉。