...
|
...
|
@@ -9,13 +9,16 @@ |
|
|
#import "YHExplorerView.h"
|
|
|
|
|
|
@interface YHExplorerView ()
|
|
|
<UIGestureRecognizerDelegate>
|
|
|
@property (strong, nonatomic) YHExplorerViewController *webViewController;
|
|
|
@property (strong, nonatomic) NSString *url;
|
|
|
@property (assign, nonatomic) BOOL isLoaded;
|
|
|
@property (strong, nonatomic) UITapGestureRecognizer *tapGesture;
|
|
|
|
|
|
@end
|
|
|
|
|
|
@implementation YHExplorerView
|
|
|
|
|
|
- (instancetype)initWithFrame:(CGRect)frame withNaviBar:(UINavigationBar *)naviBar
|
|
|
{
|
|
|
self = [self initWithFrame:frame];
|
...
|
...
|
@@ -27,7 +30,7 @@ |
|
|
{
|
|
|
self = [super initWithFrame:frame];
|
|
|
if (self) {
|
|
|
self.isLoaded = NO;
|
|
|
[self _initialize];
|
|
|
}
|
|
|
|
|
|
return self;
|
...
|
...
|
@@ -37,12 +40,17 @@ |
|
|
{
|
|
|
self = [super initWithCoder:aDecoder];
|
|
|
if (self) {
|
|
|
self.isLoaded = NO;
|
|
|
[self _initialize];
|
|
|
}
|
|
|
|
|
|
return self;
|
|
|
}
|
|
|
|
|
|
- (void)_initialize {
|
|
|
self.isLoaded = NO;
|
|
|
self.enablePictureTapGesture = NO;
|
|
|
}
|
|
|
|
|
|
- (void)setUrl:(NSString *)url
|
|
|
{
|
|
|
// 检验url是否能正常转成NSURL,防止webview不能加载
|
...
|
...
|
@@ -67,6 +75,9 @@ |
|
|
- (void)didMoveToWindow
|
|
|
{
|
|
|
if (!self.window) {
|
|
|
if (_tapGesture) {
|
|
|
[self removeGestureRecognizer:self.tapGesture];
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
|
...
|
...
|
@@ -77,6 +88,11 @@ |
|
|
[self.webViewController loadWebUrl:self.url];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (self.enablePictureTapGesture) {
|
|
|
[self addGestureRecognizer:self.tapGesture];
|
|
|
[self.tapGesture requireGestureRecognizerToFail:self.webView.scrollView.panGestureRecognizer];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- (void)layoutSubviews
|
...
|
...
|
@@ -104,6 +120,13 @@ |
|
|
}
|
|
|
}
|
|
|
|
|
|
- (void)loadHTMLString:(NSString *)html baseURL:(nullable NSURL *)baseURL
|
|
|
{
|
|
|
if (self.isLoaded) {
|
|
|
[self.webViewController loadHTMLString:html baseURL:baseURL];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- (void)setProgressBarColor:(UIColor *)color
|
|
|
{
|
|
|
[self.webViewController setProgressBarColor:color];
|
...
|
...
|
@@ -123,6 +146,16 @@ |
|
|
return self.webViewController.webView;
|
|
|
}
|
|
|
|
|
|
- (UITapGestureRecognizer *)tapGesture {
|
|
|
if (!_tapGesture) {
|
|
|
_tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hanldeTapGesture:)];
|
|
|
_tapGesture.delegate = self;
|
|
|
}
|
|
|
return _tapGesture;
|
|
|
}
|
|
|
|
|
|
#pragma mark - Setters
|
|
|
|
|
|
- (void)setDelegate:(id<YHExplorerDelegate>)delegate
|
|
|
{
|
|
|
self.webViewController.delegate = delegate;
|
...
|
...
|
@@ -140,11 +173,173 @@ |
|
|
|
|
|
}
|
|
|
|
|
|
- (void)setEnablePictureTapGesture:(BOOL)enablePictureTapGesture {
|
|
|
_enablePictureTapGesture = enablePictureTapGesture;
|
|
|
|
|
|
if (!self.window) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (enablePictureTapGesture) {
|
|
|
if (self.superview) {
|
|
|
[self addGestureRecognizer:self.tapGesture];
|
|
|
[self.tapGesture requireGestureRecognizerToFail:self.webView.scrollView.panGestureRecognizer];
|
|
|
}
|
|
|
} else {
|
|
|
if (_tapGesture) {
|
|
|
[self removeGestureRecognizer:self.tapGesture];
|
|
|
self.tapGesture = nil;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- (BOOL)enableProgressBar
|
|
|
{
|
|
|
return self.webViewController.progressBarEnabled;
|
|
|
}
|
|
|
|
|
|
#pragma mark - Private
|
|
|
- (NSString *)_getImageScriptStringWithPoint:(CGPoint)p {
|
|
|
NSString *string = [NSString stringWithFormat:@"var imageElement = document.elementFromPoint(%f, %f);\
|
|
|
var rect = imageElement.getBoundingClientRect();\
|
|
|
var frame = {x:rect.left, y:rect.top, width:rect.width, height:rect.height};\
|
|
|
var className = imageElement.className;\
|
|
|
var dataSet = { url:imageElement.src, displayFrame:frame, class:className, tagName:imageElement.tagName, id:imageElement.id };\
|
|
|
JSON.stringify(dataSet);", p.x, p.y];
|
|
|
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) {
|
|
|
return YES;
|
|
|
} else {
|
|
|
return NO;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#pragma mark - Gesture Handlers
|
|
|
- (void)hanldeTapGesture:(UITapGestureRecognizer *)gesture {
|
|
|
if (gesture == _tapGesture) {
|
|
|
|
|
|
CGFloat displayWidth = [[self.webView stringByEvaluatingJavaScriptFromString:@"window.innerWidth"] floatValue];
|
|
|
CGFloat scale = self.webView.frame.size.width / displayWidth;
|
|
|
CGPoint touchPoint = [gesture locationInView:self.webView];
|
|
|
// 如果webview是zoom状态,把对应的比例除去
|
|
|
touchPoint.x /= scale;
|
|
|
touchPoint.y /= scale;
|
|
|
|
|
|
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];
|
|
|
|
|
|
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];
|
|
|
|
|
|
if (resultString.length) {
|
|
|
|
|
|
NSData *resultData = [resultString dataUsingEncoding:NSUTF8StringEncoding];
|
|
|
|
|
|
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:resultData
|
|
|
options:0
|
|
|
error:nil];
|
|
|
|
|
|
if (json) {
|
|
|
|
|
|
NSString *tagName = [json[@"tagName"] lowercaseString];
|
|
|
|
|
|
if ([tagName isEqualToString:@"img"] && [self.delegate respondsToSelector:@selector(explorer:didClickPicture:)]) {
|
|
|
[self.delegate explorer:self.webViewController didClickPicture:json];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#pragma mark - Method Forwarding
|
|
|
- (BOOL)respondsToSelector:(SEL)aSelector
|
...
|
...
|
|