阻止UIWebView在垂直方向上“弹跳”?

229

1
我希望你考虑过禁用该功能的可用性影响。它存在是有原因的。话虽如此,我也很好奇你会怎么做。 - Michael Haren
我在我的应用程序中嵌入的方式是,它与其他视图元素无缝地显示出来,唯一不这样显示的情况是当发生弹跳时... 不过这绝对是一个好观点! - Brad Parks
22个回答

430
for (id subview in webView.subviews)
  if ([[subview class] isSubclassOfClass: [UIScrollView class]])
    ((UIScrollView *)subview).bounces = NO;

看起来运作良好。

也可以被接受到应用商店。

更新:在 iOS 5.x+ 中有一种更简单的方法 - UIWebView 有一个 scrollView 属性,所以你的代码可以像这样:

webView.scrollView.bounces = NO;

WKWebView 同样适用。


2
这个修复似乎只在我的OS 4.1模拟器上有效,而不是在我的OS 3.1.3 iPhone上。有人知道这个修复只适用于特定的操作系统版本吗? - Dan J
6
这对我很有效。为了方便起见,我给UIWebView添加了一个类别,这样我就可以在任何需要的地方调用[webView setBounces:NO] - zekel
为什么你把点符号标记为旧的?难道属性的点符号表示法不是相对较新的吗? - Dan2552
如果您更喜欢使用方括号语法... [self.webView.scrollView setBounces:NO]; - David Douglas
这在Swift中也适用,但我必须执行webView?.scrollView.bounces = false; - luckyging3r
显示剩余6条评论

46

我正在查看一个名为QuickConnect的项目,它使得在iPhone上创建Web应用程序作为完整的可安装应用程序变得容易,并找到了一个解决方案,如果您不希望屏幕可以滚动,那么这个解决方案适合我。

在上述项目/博客文章中,他们提到了一个JavaScript函数,您可以添加该函数以关闭弹跳效果,其本质归结为以下内容:

    document.ontouchmove = function(event){
        event.preventDefault();
    }

如果您想了解更多关于他们如何实现它的信息,只需下载QuickConnect并查看即可...但基本上它所做的就是在页面加载时调用那个javascript...我尝试将其放在文档头部,似乎也可以正常工作。

这个答案是在UIWebView中停止垂直滚动内容的正确方法。 - Jessedc
3
你本可以完整回答我的问题,首先我不想下载另一个应用程序的全部源代码,而且我找不到它。你的回答依赖于另一个网站在你回答时与现在保持一致。 - Jonathan.
这个回答和上面被接受的回答似乎有时是必需的。在我的情况下,我发现如果网页视图还没有加载,弹性会一直存在,直到上面的JS实际加载到系统中为止。因此,答案似乎是这个回答和上面被接受的回答有时都是必需的。 - Kalle
3
如Jessedc所说,这将停止垂直滚动,而不仅仅是弹跳。这意味着如果你有需要滚动的div或其他元素,它将不会滚动。 - memical

18

我用以下方法实现了这个:

UIView *firstView = [webView.subviews firstObject];

if ([firstView isKindOfClass:[UIScrollView class]]) {

    UIScrollView *scroll = (UIScrollView*)firstView;
   [scroll setScrollEnabled:NO];  //to stop scrolling completely
   [scroll setBounces:NO]; //to stop bouncing 

}

对我来说运行良好... 此问题的被选答案,如果您在 iPhone 应用程序中使用它,苹果将会拒绝。


3
这是最好的、最简单的方法。这应该成为被接受的答案!+1 - PostCodeism
3
不要这样做 - 我的应用因为使用了第一行代码而被拒绝了。对我来说浪费了很多时间。我使用了[[webView.subviews lastObject] setScrollEnabled:NO];,但是苹果公司认为它是私有API,因此拒绝了我的应用;现在我即将重新提交,但是我使用了"userInteractionEnabled:NO",因为我不需要应用中的任何活动链接。 - Veeru
UIWebView继承自UIView。UIView具有属性subviews。这里有什么是私有的?您可以在developer.apple.com上找到所有这些信息。 - Valerii Pavlov
3
我在App Store上有大约4个应用程序使用了这个。你的应用明显是因为其他原因被拒绝的,而不是因为使用了私有API。 - Zigglzworth
4
这真的不是一个好主意。你现在依赖于UIWebView的第一个子视图是UIScrollView,虽然这可能是目前的情况,但在未来(即使是小的)iOS更新或特定配置中,情况很容易发生变化。你应该真正做一个for迭代来找到UIScrollView(实际上并不需要太多工作),至少你可以确保得到一个UIScrollView而不会崩溃你的程序... - Jonathan Ellis
@Jonathan Ellis:我更新了我的代码,以在对其进行调用之前检查第一个子视图是否为滚动视图。虽然这仍然假设第一个子视图是滚动视图,但这种情况发生的可能性非常小,即使发生了变化,代码现在也不会崩溃。(使用for循环似乎有些过度,未来可能还会有其他滚动视图需要注意,因此我认为这样做存在风险) - Zigglzworth

17
在iOS 5 SDK中,您可以直接访问与Web视图相关联的滚动视图,而无需通过其子视图进行迭代。

因此,要禁用滚动视图中的“弹跳”,您可以使用:

myWebView.scrollView.bounces = NO;

请查看UIWebView类参考文献。(但是如果您需要支持5.0之前的SDK版本,请按照 Mirek Rusin 建议。)


12

Swift 3

webView.scrollView.bounces = false

9

警告。我在我的应用中使用了setAllowsRubberBanding:,然后苹果公司拒绝了它,称不允许使用非公共API函数(引用:3.3.1)。


4
在Swift中禁用弹性效果
webViewObj.scrollView.bounces = false

3

Brad的方法对我很有效。如果您使用它,您可能希望让它更加安全。

id scrollView = [yourWebView.subviews objectAtIndex:0];
if( [scrollView respondsToSelector:@selector(setAllowsRubberBanding:)] )
{
    [scrollView performSelector:@selector(setAllowsRubberBanding:) withObject:NO];
}

如果苹果公司做了一些改变,那么弹跳效果将会回来 - 但至少您的应用程序不会崩溃。


3

仅在iOS5上,如果您计划让用户缩放Web视图内容(例如:双击),则弹跳设置是不够的。您还需要将alwaysBounceHorizontal和alwaysBounceVertical属性设置为NO,否则当他们缩小到默认大小时(另一个双击...),它会再次弹跳。


2
我遍历了UIWebView的子视图集合,并将它们的背景设置为[UIColor blackColor],与网页背景颜色相同。视图仍然会反弹,但不会显示那个丑陋的深灰色背景。

1
实际上这是一个相当糟糕的方法,因为如果苹果公司改变了UIWebView的内部结构,这个hack可能会失效。 - bpapa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接