Authored by 戴强

Merge branch 'dev_cordova' into 'master'

Dev cordova



See merge request !2
... ... @@ -61,15 +61,26 @@
if ([weakIf respondsToSelector:@selector(nativeActionDidTriggerEventWithUserInfo:completion:)]) {
[weakIf nativeActionDidTriggerEventWithUserInfo:info
completion:^(NSDictionary *callbackInfo, BOOL result) {
completion:^(id callbackInfo, BOOL result) {
CDVPluginResult *pluginResult;
CDVCommandStatus cmdStatus = CDVCommandStatus_ERROR;
if (result) {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:callbackInfo];
cmdStatus = CDVCommandStatus_OK;
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:callbackInfo];
cmdStatus = CDVCommandStatus_ERROR;
}
if ([callbackInfo isKindOfClass:[NSString class]]) {
pluginResult = [CDVPluginResult resultWithStatus:cmdStatus messageAsString:(NSString *)callbackInfo];
}else if ([callbackInfo isKindOfClass:[NSDictionary class]]){
pluginResult = [CDVPluginResult resultWithStatus:cmdStatus
messageAsDictionary:(NSDictionary *)callbackInfo];
}else if ([callbackInfo isKindOfClass:[NSArray class]]){
pluginResult = [CDVPluginResult resultWithStatus:cmdStatus
messageAsMultipart:(NSArray *)callbackInfo];
}
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}];
} else {
... ...
... ... @@ -28,6 +28,6 @@
* @param userInfo
* @param completion 执行结果
*/
- (void)nativeActionDidTriggerEventWithUserInfo:(NSDictionary *)userInfo completion:(void (^) (NSDictionary *, BOOL))completion;
- (void)nativeActionDidTriggerEventWithUserInfo:(NSDictionary *)userInfo completion:(void (^) (id, BOOL))completion;
@end
... ...
... ... @@ -16,6 +16,7 @@
#define kAnimationDurationMultiplier (1.8)
@interface YHWebViewProgressView ()
<CAAnimationDelegate>
@property (nonatomic) BOOL isWkWebView;
@property (nonatomic, strong)UIImageView *maskView;
@end
... ...
... ... @@ -16,6 +16,24 @@
*/
@property (weak, nonatomic) IBOutlet id <YHExplorerDelegate> delegate;
@property (nonatomic) BOOL enableProgressBar;
/*
* Explorer的tap手势 默认NO
* 开启后可以处理图片点击事件
*/
@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;
... ... @@ -24,4 +42,5 @@
* 移除滚动条
*/
- (void)removeProgress;
@end
... ...
... ... @@ -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
... ...
... ... @@ -28,6 +28,8 @@
* @param html 网页内容
*/
- (void)loadHTMLString:(NSString * _Nonnull)html;
- (void)loadHTMLString:(NSString *)html baseURL:(nullable NSURL *)baseURL;
/**
* 设置进度条的颜色
*
... ... @@ -137,6 +139,17 @@
*/
- (NSString * _Nullable)extraUserAgent;
/**
@brief 点击图片事件
注:需要开启 `YHExplorerView`属性`enablePictureTapGesture`
@param explorer explorer对象
@param params 图片的一些信息
@since 1.1.3
*/
- (void)explorer:(YHExplorerViewController * _Nonnull)explorer didClickPicture:(NSDictionary * _Nonnull)pictureInfo;
#pragma mark Native
/**
@brief H5端触发Native事件
... ... @@ -147,7 +160,16 @@
@since 1.1.0
*/
- (void)didGetMessageFromWeb:(NSDictionary * _Nonnull)params completion:(void (^ _Nonnull) (NSDictionary * _Nullable, BOOL))completion;
- (void)didGetMessageFromWeb:(NSDictionary * _Nonnull)params completion:(void (^ _Nonnull) (id _Nullable, BOOL))completion;
/**
由于shouldStartLoadWithRequest这个代理方法不适合对外暴露,此代理将暴露webview拦截到的请求
@param webView UIWebView
@param request 网页请求
@param navigationType 请求类型
*/
- (void)webView:(UIWebView *)webView didCatchRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
@required
@end
... ...
... ... @@ -218,6 +218,11 @@ static float kprogressViewRadius = 2.0f;
[self.webView loadHTMLString:html baseURL:[[NSBundle mainBundle] bundleURL]];
}
- (void)loadHTMLString:(NSString *)html baseURL:(nullable NSURL *)baseURL
{
[self.webView loadHTMLString:html baseURL:baseURL];
}
- (void)setProgressBarColor:(UIColor *)color
{
if (self.progressBar) {
... ... @@ -354,6 +359,10 @@ static float kprogressViewRadius = 2.0f;
return NO;
}
if ([self.delegate respondsToSelector:@selector(webView:didCatchRequest:navigationType:)]) {
[self.delegate webView:theWebView didCatchRequest:request navigationType:navigationType];
}
BOOL b = [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType];
if (self.delegate && [self.delegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) {
... ... @@ -394,7 +403,7 @@ static float kprogressViewRadius = 2.0f;
return NO;
}
- (void)nativeActionDidTriggerEventWithUserInfo:(NSDictionary *)userInfo completion:(void (^)(NSDictionary *, BOOL))completion {
- (void)nativeActionDidTriggerEventWithUserInfo:(NSDictionary *)userInfo completion:(void (^)(id, BOOL))completion {
dispatch_async(dispatch_get_main_queue(), ^{
if ([self.delegate respondsToSelector:@selector(didGetMessageFromWeb:completion:)]) {
... ...
... ... @@ -58,7 +58,7 @@
WebViewController *wv = [self.storyboard instantiateViewControllerWithIdentifier:@"wc"];
if ([title isEqualToString:@"链接跳转"]) {
wv.url = @"http://sealedace.com/content/images/test/h5_test.html";
wv.url = @"http://m.yohobuy.com";
} else {
wv.url = @"http://localhost";
}
... ...
... ... @@ -13,6 +13,8 @@
<YHExplorerDelegate>
@property (weak, nonatomic) IBOutlet YHExplorerView *webView;
@property (strong, nonatomic) UITextView *tv;
@property (strong, nonatomic) UIVisualEffectView *blurView;
@property (strong, nonatomic) UIImageView *displayPictureView;
@end
@implementation WebViewController
... ... @@ -32,6 +34,27 @@
return YES;
}
- (UIVisualEffectView *)blurView {
if (!_blurView) {
UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
_blurView = [[UIVisualEffectView alloc] initWithEffect:effect];
_blurView.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 200.f);
[_blurView addSubview:self.displayPictureView];
_blurView.userInteractionEnabled = YES;
self.displayPictureView.frame = _blurView.bounds;
}
return _blurView;
}
- (UIImageView *)displayPictureView {
if (!_displayPictureView) {
_displayPictureView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
_displayPictureView.contentMode = UIViewContentModeScaleAspectFit;
_displayPictureView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
}
return _displayPictureView;
}
- (void)dealloc
{
... ... @@ -52,6 +75,9 @@
[super viewDidLoad];
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"]];
... ... @@ -68,6 +94,21 @@
// [self.webView loadHTMLString:html];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (self.blurView.superview) {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[self performSelector:@selector(hideBlurView) withObject:nil afterDelay:2];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
#pragma mark - YHExplorerDelegate
- (void)pageTitleUpdated:(NSString *)title
{
... ... @@ -117,4 +158,80 @@
self.tv.text = [[NSString alloc] initWithFormat:@"url: %@\nopentype: %@\nopenParams:\n%@", freshUrl, openType, openParameters];
}
// H5上点击了图片的事件
- (void)explorer:(YHExplorerViewController *)explorer didClickPicture:(NSDictionary *)pictureInfo {
NSLog(@"explorer didClickPicture: \n%@", pictureInfo);
// 获取点击的img的url
NSString *imageUrl = pictureInfo[@"url"];
// 如果为空,那么不处理
if (imageUrl.length == 0) {
return;
}
// 如果要根据class里含有`product-picture`的来执行逻辑,参考如下代码:
#if 0
NSString *destClassName = @"product-picture";
BOOL matchClass = NO;
NSString *classString = pictureInfo[@"class"];
NSArray<NSString *> *classArray = [classString componentsSeparatedByString:@" "];
for (NSString *aClass in classArray) {
if ([aClass isEqualToString:destClassName]) {
matchClass = YES;
break;
}
}
if (!matchClass) {
return;
}
#endif
//
CGFloat width = CGRectGetWidth(self.view.frame);
CGFloat height = CGRectGetHeight(self.view.frame)-CGRectGetMaxY(self.navigationController.navigationBar.frame);
self.blurView.frame = CGRectMake((CGRectGetWidth(self.view.frame)-width)/2,
CGRectGetHeight(self.view.frame)+height,
width,
height);
if (self.blurView.superview) {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hideBlurView) object:nil];
[self performSelector:@selector(hideBlurView) withObject:nil afterDelay:2];
} else {
[self.view addSubview:self.blurView];
[UIView animateWithDuration:0.7
delay:0
usingSpringWithDamping:1
initialSpringVelocity:0.5
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
CGPoint center = self.blurView.center;
self.blurView.center = CGPointMake(center.x, CGRectGetHeight(self.view.frame)-height/2);
} completion:^(BOOL finished) {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hideBlurView) object:nil];
[self performSelector:@selector(hideBlurView) withObject:nil afterDelay:2];
}];
}
// 从url加载图片
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
self.displayPictureView.image = [UIImage imageWithData:imageData scale:0];
}
- (void)hideBlurView {
[UIView animateWithDuration:0.7
delay:0
usingSpringWithDamping:1
initialSpringVelocity:0.5
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
CGPoint center = self.blurView.center;
self.blurView.center = CGPointMake(center.x, CGRectGetHeight(self.view.frame)+CGRectGetHeight(self.blurView.frame)/2);
} completion:^(BOOL finished) {
[self.blurView removeFromSuperview];
}];
}
@end
... ...