UIWebView 内容偏移 [英] UIWebView Content Offset

查看:48
本文介绍了UIWebView 内容偏移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的应用程序中将 google.maps url 显示到 UIWebView 中,但该页面出现的点与我想要的不同.我在这里尝试了许多问题的所有内容,例如设置 webview.scrollview 或 contentInset 或 scrollsToTop 的 contentOffset 或什至使用 javascript 命令,但它们都不起作用.所以这就是问题所在:

这是我想要的预期结果:

我希望我的网页出现在顶部而不是中间.

网址:

解决方案

这与内容偏移等无关 - 它是页面本身在完成加载后立即向下滚动.在 Mobile Safari 中加载 URL 时,您将获得完全相同的行为,甚至可以观察到滚动动画.

不幸的是,除了在将滚动代码加载到 webview 之前从服务器提供的 html 中提取滚动代码之外,您无法采取任何措施来阻止它.这会很乏味,无论如何您都不应该这样做,因为一旦谷歌对该页面的内部工作方式进行更改,这可能会破坏您的应用.

我现在能想到的唯一解决方案是在页面向下滚动后以编程方式将页面滚动回顶部.我已经用你提供的网址试过了,它确实有效.为此,请在您的 webview 委托中实现 webViewDidFinishLoad: ,如下所示:

-(void)webViewDidFinishLoad:(UIWebView *)webView {NSTimer *scrollTimer = [NSTimer scheduleTimerWithTimeInterval:2 target:self selector:@selector(scrollBackToTop) userInfo:nil repeats:NO];//最好将计时器设为 ivar}

并实现如下方法:

-(void)scrollBackToTop {NSString* javascript = [NSString stringWithFormat:@"window.scrollTo(0, 0);"];[theWebView stringByEvaluatingJavaScriptFromString:javascript];}

这当然意味着您的 webview 将首先明显向下滚动,然后跳回顶部,这很丑陋.因此,您可能希望将 webview 隐藏在包含活动指示器等的不透明视图后面,直到 webview 加载并完成所有滚动操作...

请注意,虽然可能性较小且致命性较低,但它也可能会损坏.当我尝试我的解决方案时,2 秒的延迟就足够了.但是,如果 google 将来放慢动画速度,2 秒可能还不够,并且您的 scrollBackToTop 方法会提前触发.由于 java 脚本不会取消正在进行的滚动,因此它根本不会滚动回顶部.

也许我有更好的东西给你...

在您的 webViewDidFinishLoad: 方法中执行以下操作:

NSString* javascript = [NSString stringWithFormat:@"document.getElementById('panel').style.position='fixed'; document.getElementById('panel').style.top='50px';"];[webView stringByEvaluatingJavaScriptFromString:javascript];

这将完全抑制滚动动画.但这是有代价的:如果用户现在手动滚动 webview,表单字段将保持固定位置,而页面的其余部分则正常滚动.

所以你需要通过这样做来撤消黑客攻击:

NSString* javascript = [NSString stringWithFormat:@"document.getElementById('panel').style.position='absolute'; document.getElementById('panel').style.top='0px';"];[theWebView stringByEvaluatingJavaScriptFromString:javascript];

您需要再次延迟执行第二步,在滚动脚本完成后,否则页面将进行完整滚动.对我来说,1.2 秒的延迟就成功了.

您可能希望通过在计时器触发之前禁用 webviews 滚动视图上的滚动来阻止用户在这 1.2 秒内滚动.

所以仍有改进的空间,但与隐藏 webview 直到它来回滚动相比,这种方法可能会让您的应用感觉更灵敏...

I want to show a google.maps url into a UIWebView in my app but the page comes up in different point from this that i want. I tried everything of many questions here such as set contentOffset of webview.scrollview or contentInset or scrollsToTop or even with javascript commands but neither of them works.So this is the problem:

and this is the expected result that i would like to have:

I want my webpage to come up on top and not in the middle.

url: url

解决方案

This has nothing to do with content offsets etc. - it is the page itself which scrolls down right after it finished loading. When loading the URL in Mobile Safari, you will get the exact same behaviour and can even observe the scrolling animation.

Unfortunately, there is nothing you can do to prevent it, except extracting the scroll code from the html the server delivers before loading it in the webview. This would be tedious and you shouldn't do it anyway, since this will likely break your app once changes are made by google to the inner workings of that page.

The only solution I can think of right now is to scroll the page back to top programmatically after it has scrolled down. I've tried it with the url you provided and it acutally works. To do this, implement webViewDidFinishLoad: in your webview delegate like so:

-(void)webViewDidFinishLoad:(UIWebView *)webView {

   NSTimer *scrollTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(scrollBackToTop) userInfo:nil repeats:NO]; // Better make the timer an ivar

}

and implement a method like:

-(void)scrollBackToTop {

   NSString* javascript = [NSString stringWithFormat:@"window.scrollTo(0, 0);"];
   [theWebView stringByEvaluatingJavaScriptFromString:javascript];

}

This means of course that your webview will first scroll down visibly only to jump back to top, which is rather ugly. So you may want to hide the webview behind an opaque view containing an activity indicator or the like until the webview has loaded and finished all of the scrolling action...

Be aware though that, while less likely and less lethally, this may break as well. When I tried my solution, a 2 second delay was sufficient. If google slows down the animation in the future though, 2 seconds might not be enough and your scrollBackToTop method fires early. Since the java script will not cancel the scroll in progress, it won't scroll back to top at all.

Edit:

Maybe I have something better for you...

Do the following in your webViewDidFinishLoad: method:

NSString* javascript = [NSString stringWithFormat:@"document.getElementById('panel').style.position='fixed'; document.getElementById('panel').style.top='50px';"];
[webView stringByEvaluatingJavaScriptFromString:javascript];

This will completely suppress the scrolling animation. But it comes at a cost: If the user scrolls the webview manually now, the form fields remain fixed in position, while the rest of the page is scrolling normally.

So you need to undo the hack, by doing this:

NSString* javascript = [NSString stringWithFormat:@"document.getElementById('panel').style.position='absolute'; document.getElementById('panel').style.top='0px';"];
[theWebView stringByEvaluatingJavaScriptFromString:javascript];

You need to execute the second step with a delay again, after the scroll script has finished, otherwise the page will do the full scroll. For me, a 1.2 second delay did the trick.

You might want to prevent the user from scrolling during those 1.2 seconds by disabling scrolling on the webviews scrollview until the timer fires.

So there's still room for improvement, but this approach will probably make your app feel more responsive, compared to hiding the webview until it has scrolled back and forth...

这篇关于UIWebView 内容偏移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆