Authored by gaoqiang xu

[feature] 支持对点击区域增加限制,可以控制对指定的id和class的元素 进行图片点击事件的处理 reviewed by 孙凯

... ... @@ -21,6 +21,19 @@
* 开启后可以处理图片点击事件
*/
@property (nonatomic) BOOL enablePictureTapGesture;
/*
* 给Explorer的tap手势添加一个区域控制(根据id获取)
* 1. id在`constraintIdsForPictureTapGesture`中的element认为是有效区域
* 2. 如果nil,不设置限定
*/
@property (strong, nonatomic) NSArray<NSString*> *constraintIdsForPictureTapGesture;
/*
* 给Explorer的tap手势添加一个区域控制(根据class获取)
* 1. class为`constraintClassesForPictureTapGesture`中的element认为是有效区域
* 2. 如果nil,不设置限定
*/
@property (strong, nonatomic) NSArray<NSString*> *constraintClassesForPictureTapGesture;
@property (weak, nonatomic) UINavigationBar * currentNaviBar;
- (UIWebView *)webView;
... ...
... ... @@ -209,6 +209,32 @@
return string;
}
- (NSString *)_getJsStringToValidateGestureAreaById {
if (self.constraintIdsForPictureTapGesture.count == 0) {
return nil;
}
NSMutableString *jsString = [[NSMutableString alloc] initWithString:@"var frameArray = [];"];
for (NSUInteger i=0; i<self.constraintIdsForPictureTapGesture.count; i++) {
[jsString appendFormat:@"var ele%zd = document.getElementById('%@');var rect%zd = ele%zd.getBoundingClientRect();var frame%zd = {x:rect%zd.left, y:rect%zd.top, width:rect%zd.width, height:rect%zd.height};frameArray.push(frame%zd);", i, self.constraintIdsForPictureTapGesture[i], i, i, i, i, i, i, i, i];
}
[jsString appendString:@"JSON.stringify(frameArray);"];
return jsString;
}
- (NSString *)_getJsStringToValidateGestureAreaByClass {
if (self.constraintClassesForPictureTapGesture.count == 0) {
return nil;
}
NSMutableString *jsString = [[NSMutableString alloc] initWithString:@"var frameArray = [];"];
for (NSUInteger i=0; i<self.constraintClassesForPictureTapGesture.count; i++) {
[jsString appendFormat:@"var ele%zd = document.getElementsByClassName('%@');for (var i=0;i<ele%zd.length;i++) {var ele = ele%zd[i]; var rect = ele.getBoundingClientRect();var frame = {x:rect.left, y:rect.top, width:rect.width, height:rect.height};frameArray.push(frame);}", i, self.constraintClassesForPictureTapGesture[i], i, i];
}
[jsString appendString:@"JSON.stringify(frameArray);"];
return jsString;
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if (gestureRecognizer == _tapGesture) {
... ... @@ -221,8 +247,73 @@
#pragma mark - Gesture Handlers
- (void)hanldeTapGesture:(UITapGestureRecognizer *)gesture {
if (gesture == _tapGesture) {
CGPoint touchPoint = [gesture locationInView:self.webView];
BOOL validArea = YES;
BOOL validIdArea = YES;
BOOL validClassArea = YES;
if (self.constraintIdsForPictureTapGesture.count) {
validIdArea = NO;
NSString *frameArrayString = [self.webView stringByEvaluatingJavaScriptFromString:[self _getJsStringToValidateGestureAreaById]];
if (frameArrayString.length) {
NSData *resultData = [frameArrayString dataUsingEncoding:NSUTF8StringEncoding];
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:resultData
options:0
error:nil];
if (jsonArray.count == self.constraintIdsForPictureTapGesture.count) {
for (NSDictionary *dic in jsonArray) {
NSNumber *rectX = dic[@"x"];
NSNumber *rectY = dic[@"y"];
NSNumber *rectWidth = dic[@"width"];
NSNumber *rectHeight = dic[@"height"];
CGRect rect = CGRectMake(rectX?rectX.doubleValue:0, rectY?rectY.doubleValue:0, rectWidth?rectWidth.doubleValue:0, rectHeight?rectHeight.doubleValue:0);
if (CGRectContainsPoint(rect, touchPoint)) {
validIdArea = YES;
break;
}
}
}
}
}
if (self.constraintClassesForPictureTapGesture.count) {
validClassArea = NO;
NSString *frameArrayString = [self.webView stringByEvaluatingJavaScriptFromString:[self _getJsStringToValidateGestureAreaByClass]];
if (frameArrayString.length) {
NSData *resultData = [frameArrayString dataUsingEncoding:NSUTF8StringEncoding];
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:resultData
options:0
error:nil];
if (jsonArray.count == self.constraintClassesForPictureTapGesture.count) {
for (NSDictionary *dic in jsonArray) {
NSNumber *rectX = dic[@"x"];
NSNumber *rectY = dic[@"y"];
NSNumber *rectWidth = dic[@"width"];
NSNumber *rectHeight = dic[@"height"];
CGRect rect = CGRectMake(rectX?rectX.doubleValue:0, rectY?rectY.doubleValue:0, rectWidth?rectWidth.doubleValue:0, rectHeight?rectHeight.doubleValue:0);
if (CGRectContainsPoint(rect, touchPoint)) {
validClassArea = YES;
break;
}
}
}
}
}
if (self.constraintIdsForPictureTapGesture.count > 0 && self.constraintClassesForPictureTapGesture.count > 0) {
validArea = (validIdArea || validClassArea);
} else if (self.constraintIdsForPictureTapGesture.count) {
validArea = validIdArea;
} else if (self.constraintClassesForPictureTapGesture.count) {
validArea = validClassArea;
}
if (!validArea) {
return;
}
NSString *imgURL = [self _getImageScriptStringWithPoint:touchPoint];
NSString *resultString = [self.webView stringByEvaluatingJavaScriptFromString:imgURL];
... ...
... ... @@ -76,6 +76,8 @@
self.webView.delegate = self;
self.webView.enableProgressBar = YES;
self.webView.enablePictureTapGesture = YES;
// self.webView.constraintIdsForPictureTapGesture = @[ @"productDesc", @"enter-store" ];
self.webView.constraintClassesForPictureTapGesture = @[ @"product-detail", @"wash-tips", @"measurement-method" ];
[self.webView loadWebUrl:self.url];
// [self.webView loadWebUrl:[[NSBundle mainBundle] pathForResource:@"untitled" ofType:@"html"]];
... ...