[feature] 支持H5页面图片点击捕获 reviewed by 戴强
Showing
6 changed files
with
203 additions
and
3 deletions
@@ -16,6 +16,7 @@ | @@ -16,6 +16,7 @@ | ||
16 | #define kAnimationDurationMultiplier (1.8) | 16 | #define kAnimationDurationMultiplier (1.8) |
17 | 17 | ||
18 | @interface YHWebViewProgressView () | 18 | @interface YHWebViewProgressView () |
19 | +<CAAnimationDelegate> | ||
19 | @property (nonatomic) BOOL isWkWebView; | 20 | @property (nonatomic) BOOL isWkWebView; |
20 | @property (nonatomic, strong)UIImageView *maskView; | 21 | @property (nonatomic, strong)UIImageView *maskView; |
21 | @end | 22 | @end |
@@ -16,6 +16,11 @@ | @@ -16,6 +16,11 @@ | ||
16 | */ | 16 | */ |
17 | @property (weak, nonatomic) IBOutlet id <YHExplorerDelegate> delegate; | 17 | @property (weak, nonatomic) IBOutlet id <YHExplorerDelegate> delegate; |
18 | @property (nonatomic) BOOL enableProgressBar; | 18 | @property (nonatomic) BOOL enableProgressBar; |
19 | +/* | ||
20 | + * Explorer的tap手势 默认NO | ||
21 | + * 开启后可以处理图片点击事件 | ||
22 | + */ | ||
23 | +@property (nonatomic) BOOL enablePictureTapGesture; | ||
19 | @property (weak, nonatomic) UINavigationBar * currentNaviBar; | 24 | @property (weak, nonatomic) UINavigationBar * currentNaviBar; |
20 | - (UIWebView *)webView; | 25 | - (UIWebView *)webView; |
21 | 26 | ||
@@ -24,4 +29,5 @@ | @@ -24,4 +29,5 @@ | ||
24 | * 移除滚动条 | 29 | * 移除滚动条 |
25 | */ | 30 | */ |
26 | - (void)removeProgress; | 31 | - (void)removeProgress; |
32 | + | ||
27 | @end | 33 | @end |
@@ -9,13 +9,16 @@ | @@ -9,13 +9,16 @@ | ||
9 | #import "YHExplorerView.h" | 9 | #import "YHExplorerView.h" |
10 | 10 | ||
11 | @interface YHExplorerView () | 11 | @interface YHExplorerView () |
12 | +<UIGestureRecognizerDelegate> | ||
12 | @property (strong, nonatomic) YHExplorerViewController *webViewController; | 13 | @property (strong, nonatomic) YHExplorerViewController *webViewController; |
13 | @property (strong, nonatomic) NSString *url; | 14 | @property (strong, nonatomic) NSString *url; |
14 | @property (assign, nonatomic) BOOL isLoaded; | 15 | @property (assign, nonatomic) BOOL isLoaded; |
16 | +@property (strong, nonatomic) UITapGestureRecognizer *tapGesture; | ||
15 | 17 | ||
16 | @end | 18 | @end |
17 | 19 | ||
18 | @implementation YHExplorerView | 20 | @implementation YHExplorerView |
21 | + | ||
19 | - (instancetype)initWithFrame:(CGRect)frame withNaviBar:(UINavigationBar *)naviBar | 22 | - (instancetype)initWithFrame:(CGRect)frame withNaviBar:(UINavigationBar *)naviBar |
20 | { | 23 | { |
21 | self = [self initWithFrame:frame]; | 24 | self = [self initWithFrame:frame]; |
@@ -27,7 +30,7 @@ | @@ -27,7 +30,7 @@ | ||
27 | { | 30 | { |
28 | self = [super initWithFrame:frame]; | 31 | self = [super initWithFrame:frame]; |
29 | if (self) { | 32 | if (self) { |
30 | - self.isLoaded = NO; | 33 | + [self _initialize]; |
31 | } | 34 | } |
32 | 35 | ||
33 | return self; | 36 | return self; |
@@ -37,12 +40,17 @@ | @@ -37,12 +40,17 @@ | ||
37 | { | 40 | { |
38 | self = [super initWithCoder:aDecoder]; | 41 | self = [super initWithCoder:aDecoder]; |
39 | if (self) { | 42 | if (self) { |
40 | - self.isLoaded = NO; | 43 | + [self _initialize]; |
41 | } | 44 | } |
42 | 45 | ||
43 | return self; | 46 | return self; |
44 | } | 47 | } |
45 | 48 | ||
49 | +- (void)_initialize { | ||
50 | + self.isLoaded = NO; | ||
51 | + self.enablePictureTapGesture = NO; | ||
52 | +} | ||
53 | + | ||
46 | - (void)setUrl:(NSString *)url | 54 | - (void)setUrl:(NSString *)url |
47 | { | 55 | { |
48 | // 检验url是否能正常转成NSURL,防止webview不能加载 | 56 | // 检验url是否能正常转成NSURL,防止webview不能加载 |
@@ -67,6 +75,9 @@ | @@ -67,6 +75,9 @@ | ||
67 | - (void)didMoveToWindow | 75 | - (void)didMoveToWindow |
68 | { | 76 | { |
69 | if (!self.window) { | 77 | if (!self.window) { |
78 | + if (_tapGesture) { | ||
79 | + [self removeGestureRecognizer:self.tapGesture]; | ||
80 | + } | ||
70 | return; | 81 | return; |
71 | } | 82 | } |
72 | 83 | ||
@@ -77,6 +88,11 @@ | @@ -77,6 +88,11 @@ | ||
77 | [self.webViewController loadWebUrl:self.url]; | 88 | [self.webViewController loadWebUrl:self.url]; |
78 | } | 89 | } |
79 | } | 90 | } |
91 | + | ||
92 | + if (self.enablePictureTapGesture) { | ||
93 | + [self addGestureRecognizer:self.tapGesture]; | ||
94 | + [self.tapGesture requireGestureRecognizerToFail:self.webView.scrollView.panGestureRecognizer]; | ||
95 | + } | ||
80 | } | 96 | } |
81 | 97 | ||
82 | - (void)layoutSubviews | 98 | - (void)layoutSubviews |
@@ -123,6 +139,16 @@ | @@ -123,6 +139,16 @@ | ||
123 | return self.webViewController.webView; | 139 | return self.webViewController.webView; |
124 | } | 140 | } |
125 | 141 | ||
142 | +- (UITapGestureRecognizer *)tapGesture { | ||
143 | + if (!_tapGesture) { | ||
144 | + _tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hanldeTapGesture:)]; | ||
145 | + _tapGesture.delegate = self; | ||
146 | + } | ||
147 | + return _tapGesture; | ||
148 | +} | ||
149 | + | ||
150 | +#pragma mark - Setters | ||
151 | + | ||
126 | - (void)setDelegate:(id<YHExplorerDelegate>)delegate | 152 | - (void)setDelegate:(id<YHExplorerDelegate>)delegate |
127 | { | 153 | { |
128 | self.webViewController.delegate = delegate; | 154 | self.webViewController.delegate = delegate; |
@@ -140,11 +166,71 @@ | @@ -140,11 +166,71 @@ | ||
140 | 166 | ||
141 | } | 167 | } |
142 | 168 | ||
169 | +- (void)setEnablePictureTapGesture:(BOOL)enablePictureTapGesture { | ||
170 | + _enablePictureTapGesture = enablePictureTapGesture; | ||
171 | + | ||
172 | + if (!self.window) { | ||
173 | + return; | ||
174 | + } | ||
175 | + | ||
176 | + if (enablePictureTapGesture) { | ||
177 | + if (self.superview) { | ||
178 | + [self addGestureRecognizer:self.tapGesture]; | ||
179 | + [self.tapGesture requireGestureRecognizerToFail:self.webView.scrollView.panGestureRecognizer]; | ||
180 | + } | ||
181 | + } else { | ||
182 | + if (_tapGesture) { | ||
183 | + [self removeGestureRecognizer:self.tapGesture]; | ||
184 | + self.tapGesture = nil; | ||
185 | + } | ||
186 | + } | ||
187 | +} | ||
188 | + | ||
143 | - (BOOL)enableProgressBar | 189 | - (BOOL)enableProgressBar |
144 | { | 190 | { |
145 | return self.webViewController.progressBarEnabled; | 191 | return self.webViewController.progressBarEnabled; |
146 | } | 192 | } |
147 | 193 | ||
194 | +#pragma mark - Private | ||
195 | +- (NSString *)_getImageScriptStringWithPoint:(CGPoint)p { | ||
196 | + NSString *string = [NSString stringWithFormat:@"var imageElement = document.elementFromPoint(%f, %f);\ | ||
197 | + var rect = imageElement.getBoundingClientRect();\ | ||
198 | + var frame = {x:rect.left, y:rect.top, width:rect.width, height:rect.height};\ | ||
199 | + var dataSet = { url:imageElement.src, displayFrame:frame };\ | ||
200 | + JSON.stringify(dataSet);", p.x, p.y]; | ||
201 | + return string; | ||
202 | +} | ||
203 | + | ||
204 | +#pragma mark - UIGestureRecognizerDelegate | ||
205 | +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { | ||
206 | + if (gestureRecognizer == _tapGesture) { | ||
207 | + return YES; | ||
208 | + } else { | ||
209 | + return NO; | ||
210 | + } | ||
211 | +} | ||
212 | + | ||
213 | +#pragma mark - Gesture Handlers | ||
214 | +- (void)hanldeTapGesture:(UITapGestureRecognizer *)gesture { | ||
215 | + if (gesture == _tapGesture) { | ||
216 | + CGPoint touchPoint = [gesture locationInView:self.webView]; | ||
217 | + | ||
218 | + NSString *imgURL = [self _getImageScriptStringWithPoint:touchPoint]; | ||
219 | + NSString *resultString = [self.webView stringByEvaluatingJavaScriptFromString:imgURL]; | ||
220 | + | ||
221 | + if (resultString.length) { | ||
222 | + | ||
223 | + NSData *resultData = [resultString dataUsingEncoding:NSUTF8StringEncoding]; | ||
224 | + | ||
225 | + NSDictionary *json = [NSJSONSerialization JSONObjectWithData:resultData | ||
226 | + options:0 | ||
227 | + error:nil]; | ||
228 | + if ([self.delegate respondsToSelector:@selector(explorer:didClickPicture:)]) { | ||
229 | + [self.delegate explorer:self.webViewController didClickPicture:json]; | ||
230 | + } | ||
231 | + } | ||
232 | + } | ||
233 | +} | ||
148 | 234 | ||
149 | #pragma mark - Method Forwarding | 235 | #pragma mark - Method Forwarding |
150 | - (BOOL)respondsToSelector:(SEL)aSelector | 236 | - (BOOL)respondsToSelector:(SEL)aSelector |
@@ -137,6 +137,17 @@ | @@ -137,6 +137,17 @@ | ||
137 | */ | 137 | */ |
138 | - (NSString * _Nullable)extraUserAgent; | 138 | - (NSString * _Nullable)extraUserAgent; |
139 | 139 | ||
140 | +/** | ||
141 | + @brief 点击图片事件 | ||
142 | + 注:需要开启 `YHExplorerView`属性`enablePictureTapGesture` | ||
143 | + | ||
144 | + @param explorer explorer对象 | ||
145 | + @param params 图片的一些信息 | ||
146 | + | ||
147 | + @since 1.1.3 | ||
148 | + */ | ||
149 | +- (void)explorer:(YHExplorerViewController * _Nonnull)explorer didClickPicture:(NSDictionary * _Nonnull)pictureInfo; | ||
150 | + | ||
140 | #pragma mark Native | 151 | #pragma mark Native |
141 | /** | 152 | /** |
142 | @brief H5端触发Native事件 | 153 | @brief H5端触发Native事件 |
@@ -58,7 +58,7 @@ | @@ -58,7 +58,7 @@ | ||
58 | WebViewController *wv = [self.storyboard instantiateViewControllerWithIdentifier:@"wc"]; | 58 | WebViewController *wv = [self.storyboard instantiateViewControllerWithIdentifier:@"wc"]; |
59 | 59 | ||
60 | if ([title isEqualToString:@"链接跳转"]) { | 60 | if ([title isEqualToString:@"链接跳转"]) { |
61 | - wv.url = @"http://sealedace.com/content/images/test/h5_test.html"; | 61 | + wv.url = @"http://m.yohobuy.com"; |
62 | } else { | 62 | } else { |
63 | wv.url = @"http://localhost"; | 63 | wv.url = @"http://localhost"; |
64 | } | 64 | } |
@@ -13,6 +13,8 @@ | @@ -13,6 +13,8 @@ | ||
13 | <YHExplorerDelegate> | 13 | <YHExplorerDelegate> |
14 | @property (weak, nonatomic) IBOutlet YHExplorerView *webView; | 14 | @property (weak, nonatomic) IBOutlet YHExplorerView *webView; |
15 | @property (strong, nonatomic) UITextView *tv; | 15 | @property (strong, nonatomic) UITextView *tv; |
16 | +@property (strong, nonatomic) UIVisualEffectView *blurView; | ||
17 | +@property (strong, nonatomic) UIImageView *displayPictureView; | ||
16 | @end | 18 | @end |
17 | 19 | ||
18 | @implementation WebViewController | 20 | @implementation WebViewController |
@@ -32,6 +34,27 @@ | @@ -32,6 +34,27 @@ | ||
32 | return YES; | 34 | return YES; |
33 | } | 35 | } |
34 | 36 | ||
37 | +- (UIVisualEffectView *)blurView { | ||
38 | + if (!_blurView) { | ||
39 | + UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]; | ||
40 | + _blurView = [[UIVisualEffectView alloc] initWithEffect:effect]; | ||
41 | + _blurView.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 200.f); | ||
42 | + [_blurView addSubview:self.displayPictureView]; | ||
43 | + _blurView.userInteractionEnabled = YES; | ||
44 | + self.displayPictureView.frame = _blurView.bounds; | ||
45 | + } | ||
46 | + return _blurView; | ||
47 | +} | ||
48 | + | ||
49 | +- (UIImageView *)displayPictureView { | ||
50 | + if (!_displayPictureView) { | ||
51 | + _displayPictureView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; | ||
52 | + _displayPictureView.contentMode = UIViewContentModeScaleAspectFit; | ||
53 | + _displayPictureView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; | ||
54 | + } | ||
55 | + return _displayPictureView; | ||
56 | +} | ||
57 | + | ||
35 | - (void)dealloc | 58 | - (void)dealloc |
36 | { | 59 | { |
37 | 60 | ||
@@ -52,6 +75,7 @@ | @@ -52,6 +75,7 @@ | ||
52 | [super viewDidLoad]; | 75 | [super viewDidLoad]; |
53 | self.webView.delegate = self; | 76 | self.webView.delegate = self; |
54 | self.webView.enableProgressBar = YES; | 77 | self.webView.enableProgressBar = YES; |
78 | + self.webView.enablePictureTapGesture = YES; | ||
55 | 79 | ||
56 | [self.webView loadWebUrl:self.url]; | 80 | [self.webView loadWebUrl:self.url]; |
57 | // [self.webView loadWebUrl:[[NSBundle mainBundle] pathForResource:@"untitled" ofType:@"html"]]; | 81 | // [self.webView loadWebUrl:[[NSBundle mainBundle] pathForResource:@"untitled" ofType:@"html"]]; |
@@ -68,6 +92,21 @@ | @@ -68,6 +92,21 @@ | ||
68 | // [self.webView loadHTMLString:html]; | 92 | // [self.webView loadHTMLString:html]; |
69 | } | 93 | } |
70 | 94 | ||
95 | +- (void)viewWillAppear:(BOOL)animated { | ||
96 | + [super viewWillAppear:animated]; | ||
97 | + | ||
98 | + if (self.blurView.superview) { | ||
99 | + [NSObject cancelPreviousPerformRequestsWithTarget:self]; | ||
100 | + [self performSelector:@selector(hideBlurView) withObject:nil afterDelay:2]; | ||
101 | + } | ||
102 | +} | ||
103 | + | ||
104 | +- (void)viewWillDisappear:(BOOL)animated { | ||
105 | + [super viewWillDisappear:animated]; | ||
106 | + | ||
107 | + [NSObject cancelPreviousPerformRequestsWithTarget:self]; | ||
108 | +} | ||
109 | + | ||
71 | #pragma mark - YHExplorerDelegate | 110 | #pragma mark - YHExplorerDelegate |
72 | - (void)pageTitleUpdated:(NSString *)title | 111 | - (void)pageTitleUpdated:(NSString *)title |
73 | { | 112 | { |
@@ -117,4 +156,61 @@ | @@ -117,4 +156,61 @@ | ||
117 | self.tv.text = [[NSString alloc] initWithFormat:@"url: %@\nopentype: %@\nopenParams:\n%@", freshUrl, openType, openParameters]; | 156 | self.tv.text = [[NSString alloc] initWithFormat:@"url: %@\nopentype: %@\nopenParams:\n%@", freshUrl, openType, openParameters]; |
118 | } | 157 | } |
119 | 158 | ||
159 | +// H5上点击了图片的事件 | ||
160 | +- (void)explorer:(YHExplorerViewController *)explorer didClickPicture:(NSDictionary *)pictureInfo { | ||
161 | + NSLog(@"explorer didClickPicture: \n%@", pictureInfo); | ||
162 | + | ||
163 | + NSString *imageUrl = pictureInfo[@"url"]; | ||
164 | + | ||
165 | + if (imageUrl.length == 0) { | ||
166 | + return; | ||
167 | + } | ||
168 | + | ||
169 | + CGFloat width = CGRectGetWidth(self.view.frame); | ||
170 | + CGFloat height = CGRectGetHeight(self.view.frame)-CGRectGetMaxY(self.navigationController.navigationBar.frame); | ||
171 | + | ||
172 | + self.blurView.frame = CGRectMake((CGRectGetWidth(self.view.frame)-width)/2, | ||
173 | + CGRectGetHeight(self.view.frame)+height, | ||
174 | + width, | ||
175 | + height); | ||
176 | + | ||
177 | + if (self.blurView.superview) { | ||
178 | + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hideBlurView) object:nil]; | ||
179 | + [self performSelector:@selector(hideBlurView) withObject:nil afterDelay:2]; | ||
180 | + } else { | ||
181 | + | ||
182 | + [self.view addSubview:self.blurView]; | ||
183 | + [UIView animateWithDuration:0.7 | ||
184 | + delay:0 | ||
185 | + usingSpringWithDamping:1 | ||
186 | + initialSpringVelocity:0.5 | ||
187 | + options:UIViewAnimationOptionCurveEaseInOut | ||
188 | + animations:^{ | ||
189 | + CGPoint center = self.blurView.center; | ||
190 | + self.blurView.center = CGPointMake(center.x, CGRectGetHeight(self.view.frame)-height/2); | ||
191 | + } completion:^(BOOL finished) { | ||
192 | + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hideBlurView) object:nil]; | ||
193 | + [self performSelector:@selector(hideBlurView) withObject:nil afterDelay:2]; | ||
194 | + }]; | ||
195 | + } | ||
196 | + | ||
197 | + // 从url加载图片 | ||
198 | + NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]]; | ||
199 | + self.displayPictureView.image = [UIImage imageWithData:imageData scale:0]; | ||
200 | +} | ||
201 | + | ||
202 | +- (void)hideBlurView { | ||
203 | + [UIView animateWithDuration:0.7 | ||
204 | + delay:0 | ||
205 | + usingSpringWithDamping:1 | ||
206 | + initialSpringVelocity:0.5 | ||
207 | + options:UIViewAnimationOptionCurveEaseInOut | ||
208 | + animations:^{ | ||
209 | + CGPoint center = self.blurView.center; | ||
210 | + self.blurView.center = CGPointMake(center.x, CGRectGetHeight(self.view.frame)+CGRectGetHeight(self.blurView.frame)/2); | ||
211 | + } completion:^(BOOL finished) { | ||
212 | + [self.blurView removeFromSuperview]; | ||
213 | + }]; | ||
214 | +} | ||
215 | + | ||
120 | @end | 216 | @end |
-
Please register or login to post a comment