gpt4 book ai didi

javascript - WKWebView 自定义长按菜单可以工作,但有一些主要问题

转载 作者:技术小花猫 更新时间:2023-10-29 11:07:14 36 4
gpt4 key购买 nike

当用户长按链接时,会出现带有以下选项的警报 Controller :

  • 打开
  • 在新标签页中打开
  • 复制

目前有两个问题:

  1. 如果用户在 WKWebView 完成导航之前执行长按,则会出现默认(Safari 的)警报 Controller 。

  2. 如果用户在弹出动画发生后抬起手指,WKWebView 会将其注册为点击并导航到该链接,同时警报 Controller 仍显示在屏幕上。

该机制分为三个部分。

首先,

在 WKWebView 完成导航后,javascript 将被注入(inject)禁用默认警报 Controller 的页面。

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
[_webView evaluateJavaScript:@"document.body.style.webkitTouchCallout='none';"
completionHandler:^(id result, NSError *error){

NSLog(@"Javascript: {%@, %@}", result, error.description);
}];
}

其次,

UILongPressGestureRecognizer 被添加到 WKWebView 并实现,以便它根据触摸的位置找到元素的属性。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}

- (void)longPress:(UILongPressGestureRecognizer *)longPressGestureRecognizer
{
if (longPressGestureRecognizer.state == UIGestureRecognizerStateBegan) {

_shouldCancelNavigation = YES;

CGPoint touchLocation = [longPressGestureRecognizer locationInView:_webView];

NSString *javascript = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Javascript" ofType:@"js"]
encoding:NSUTF8StringEncoding
error:nil];

[_webView evaluateJavaScript:javascript
completionHandler:^(id result, NSError *error){

NSLog(@"Javascript: {%@, %@}", result, error.description);
}];

[_webView evaluateJavaScript:[NSString stringWithFormat:@"MyAppGetHTMLElementsAtPoint(%f,%f);", touchLocation.x, touchLocation.y]
completionHandler:^(id result, NSError *error){

NSLog(@"Javascript: {%@, %@}", result, error.description);

NSString *tags = (NSString *)result;

if ([tags containsString:@",A,"]) {

[_webView evaluateJavaScript:[NSString stringWithFormat:@"MyAppGetHREFAttributeAtPoint(%f,%f);", touchLocation.x, touchLocation.y]
completionHandler:^(id result, NSError *error){

NSLog(@"Javascript: {%@, %@}", result, error.description);

NSString *urlString = (NSString *)result;

[_delegate webView:self didLongPressAtTouchLocation:touchLocation URL:[NSURL URLWithString:urlString]];
}];

return;
}

if ([tags containsString:@",IMG,"]) {

[_webView evaluateJavaScript:[NSString stringWithFormat:@"MyAppGetSRCAttributeAtPoint(%f,%f);", touchLocation.x, touchLocation.y]
completionHandler:^(id result, NSError *error){

NSLog(@"Javascript: {%@, %@}", result, error.description);

NSString *urlString = (NSString *)result;

[_delegate webView:self didLongPressAtTouchLocation:touchLocation imageWithSourceURL:[NSURL URLWithString:urlString]];
}];

return;
}
}];
}
}

最后,

呈现警报 Controller 的委托(delegate)方法在主 ViewController 上实现。

我对第二个问题的解决方案是添加一个 bool 值 shouldCancelNavigation,当警报 Controller 出现时它是 YES,当它被关闭时它是 NO。

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
if (_shouldCancelNavigation) {

decisionHandler(WKNavigationActionPolicyCancel);
}
else {

decisionHandler(WKNavigationActionPolicyAllow);
}
}

有趣的是,网络上有许多链接不需要政策决定的例子。它们就这样发生了,我无法阻止它们。

示例:http://www.dribbble.com

enter image description here

来源:http://www.icab.de/blog/2010/07/11/customize-the-contextual-menu-of-uiwebview/comment-page-3/

来源 2:https://github.com/mozilla-mobile/firefox-ios/pull/61

编辑:

这解决了第二个问题,但我不确定它不会破坏其他地方。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if ([otherGestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {

otherGestureRecognizer.enabled = NO;

otherGestureRecognizer.enabled = YES;
}

return YES;
}

编辑 2:

它确实产生了一个问题...您不能再选择文本,因为上面的代码重置了内部长按手势识别器。

编辑 3:

如果我完全删除我的实现(所有 3 个步骤)并让默认警报 Controller 在每次我长按链接时启动,第二个问题就解决了。

在您抬起手指后,Apple 的警报 Controller 会阻止 WKWebView 导航。

最佳答案

如果我没记错的话,在第二部分:

- (void)longPress:(UILongPressGestureRecognizer *)longPressGestureRecognizer
{
if (longPressGestureRecognizer.state == UIGestureRecognizerStateBegan) {

//Rest of your code ...
}
}

您正在注入(inject) javascript 以禁用系统对话框。现在在新闻结束后,WKWebview 已经收到从网络链接触发的事件。既然为时已晚,为什么不尝试检查 longPressGestureRecognizer.state 是否等于 UIGestureRecognizerStateEnded 的条件。

因此它更改为以下代码。

    if (longPressGestureRecognizer.state == UIGestureRecognizerStateEnded) {

//Rest of your code ...
}

我还没有测试过这段代码。如果它有效,会更快乐。

关于javascript - WKWebView 自定义长按菜单可以工作,但有一些主要问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43054003/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com