一起养成写作习惯!这是我参与「日新计划 4 月更文挑战」的第25天,点击查看活动详情。
支持更多控件
支持UISwitch、UISegmentedControl、UIStepper控件
这些控件都不响应UIControlEventTouchDown
类型的Action,也就是说,没有触发-sensorsdata_touchDownAction:event:
办法,因而,也就不会触发$AppClick
事情。实际上,这些控件增加的是 UIControlEventValueChanged
类型的Action
。
+ (void)load {
[UIControl sensorsdata_swizzleMethod:@selector(didMoveToSuperview) withMethod:@selector(CountData_didMoveToSuperview)];
}
- (void)CountData_didMoveToSuperview {
//调用前交换原始办法
[self CountData_didMoveToSuperview];
//判别是否为一些特殊的控件
if([self isKindOfClass:[UISwitch class]] ||
[self isKindOfClass:[UISegmentedControl class]] ||
[self isKindOfClass:[UIStepper class]]
) {
[self addTarget:self action:@selector(countData_valueChangedAction:event:) forControlEvents:UIControlEventValueChanged];
}else {
[self addTarget:self action:@selector(CountData_touchDownAction:withEvent:) forControlEvents:UIControlEventTouchDown];
}
}
-(void)countData_valueChangedAction:(UIControl *)sender event:(UIEvent *)event {
if ([self CountData_isAddMultipleTargetActionsWithDefaultEvent:UIControlEventValueChanged]) {
[[SensorsAnalyticsSDK sharedInstance]track:@"appclick" properties:nil];
}
}
-(BOOL)CountData_isAddMultipleTargetActionsWithDefaultEvent:(UIControlEvents)defaultEvent {
///假如有多个target,阐明除了增加的target,还有其他
///那么回来YES,触发$AppClick事情
if (self.allTargets.count > 2) {
return YES;
}
//假如控件本身为target,而且增加了不是UIControlEventTouchDown类型的Action
//阐明开发者以控件本身为target,而且已增加增加Action
//那么回来YES,触发$AppClick事情
if((self.allControlEvents & UIControlEventAllEvents) != UIControlEventTouchDown) {
return YES;
}
//假如控件本身为Target,而且增加了两个以上的UIControlEventTouchDown类型的Action
//阐明开发者自行增加了Action
//那么回来YES,触发$AppClick事情
if([self actionsForTarget:self forControlEvent:defaultEvent].count > 2) {
return YES;
}
return NO;
}
支持UISlider控件
给UISlider
增加的是UIControlEventTouchDown
类型的Action
,这会导致在只点击而没有滑动UISlider
时,也会触发 $AppClick
事情,咱们更希望只要手停止滑动UISlider
时,才触发$AppClick
事情。因而,需求修正UIControl+SensorsData.m
文件中的- sensorsdata_didMoveToSuperview
办法,默许也给UISlider
增加UIControlEventValueChanged
类型的Action
。
- (void)CountData_didMoveToSuperview {
//调用前交换原始办法
[self CountData_didMoveToSuperview];
//判别是否为一些特殊的控件
if([self isKindOfClass:[UISwitch class]] ||
[self isKindOfClass:[UISegmentedControl class]] ||
[self isKindOfClass:[UIStepper class]] ||
[self isKindOfClass:[UISlider class]]) {
[self addTarget:self action:@selector(countData_valueChangedAction:event:) forControlEvents:UIControlEventValueChanged];
}else {
[self addTarget:self action:@selector(CountData_touchDownAction:withEvent:) forControlEvents:UIControlEventTouchDown];
}
}
在滑动UISlider
过程中,会一直触发$AppClick
事情。因而,咱们还需求修正UIControl+CountData.m
文件中 的-CountData_valueChanged Action:event:
办法,确保假如是UISlider
控件, 只要在手抬起的时分才触发$AppClick
事情。
-(void)countData_valueChangedAction:(UIControl *)sender event:(UIEvent *)event {
if ([sender isKindOfClass:UISlider.class] && event.allTouches.anyObject.phase != UITouchPhaseEnded) {
return;
}
if ([self CountData_isAddMultipleTargetActionsWithDefaultEvent:UIControlEventValueChanged]) {
[[SensorsAnalyticsSDK sharedInstance]track:@"appclick" properties:nil];
}
}
这样处理之后,当咱们滑动UISlider时,只会在手抬起时触发 $AppClick
事情。
计划总结
计划一和计划二其实都运用了iOS中的Target- Action
形式,这两种计划各有好坏。
-
关于计划一:假如给一个控件增加了多个
Target-Action
,会导致多次触发$AppClick事情。 -
关于计划二:因为SDK为控件增加了一个默许触发类型的
Action
,因而,假如开发者在开发 过程中使用UIControl
类的allTargets
或者allControlEvents
特点进行逻辑判别,有可能会引进一些无法意料的问题。 因而,在挑选计划的时分,读者可以根据自 己的实际情况和需求,来确定终究的实现计划。