为啥 UIWebView 不滚动?

Posted

技术标签:

【中文标题】为啥 UIWebView 不滚动?【英文标题】:Why does UIWebView Not Scroll?为什么 UIWebView 不滚动? 【发布时间】:2014-04-19 02:11:56 【问题描述】:

我已经查看了许多与此类似的问题,但尽我所能,我无法让UIWebView 以任何方式滚动或交互。代码如下:

- (void)loadView 
    [super loadView];

    ...

    [self.displayView loadhtmlString:entry->infoHtml baseURL:nil];


- (void)viewDidLoad

    [super viewDidLoad];

    self.displayView.userInteractionEnabled = YES;
    self.displayView.scrollView.showsVerticalScrollIndicator = YES;
    self.displayView.scrollView.scrollEnabled = YES;
    [self.displayView.scrollView flashScrollIndicators];

视图出现,显示所有正确的内容,并显示垂直滚动条一秒钟,正确指示当前显示的内容部分。

但我不能滚动它。触摸内容并移动我的手指根本没有任何作用。与同一父级下的非重叠 UITableView 交互工作正常;触摸那里的条目会更新 UIWebView 的内容,因为它已被编程。

UIWebView 是在 Storyboard 中使用以下选项创建的:

缩放页面以适应:未选中(选中后,也无法捏合缩放) 分页:未分页 模式:Aspect Fit(尝试了几个;全部不可滚动) UserInteractionEnabled:已选中(父视图也已选中)

视图完全可见。我试过让它比它的父级小得多,并且显示的内容总是停在正确的位置。此视图没有委托或手势识别器。

包含视图有一个UITableView 和一个UILabel,它们都不与UIWebView 的区域重叠。我已经尝试在情节提要上更改场景中视图的顺序,但这也没有任何区别。

我尝试从 UIBuilder 中删除视图并像这样以编程方式创建它:

self.displayView = [[UIWebView alloc] initWithFrame:CGRectMake(400, 220, 400, 300)];
[self.view addSubview:self.displayView];

同样的结果。我尝试从场景中删除所有其他元素,除了这个以编程方式创建的 UIWebView。结果还是一样。

在我的代码的其他地方,我将UIWebView 设置为@"accessoryView"UIAlertView,在那里我可以按预期滚动内容。

是否需要做其他事情才能滚动 UIWebView 子视图?

2014-04-20: 事实上,如果我在 -loadView 方法的底部添加以下行,我会得到一个与它后面的窗口具有相同 HTML 内容的对话框,但我能够滚动对话框版本。我能想到的唯一区别是对话框是模态的(强制焦点),而我自己的带有UITableViewUIWebView 的窗口仍然允许与它后面可见的视图进行交互。

UIWebView* contents = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 250, 250)];
[contents loadHTMLString:entry->infoHtml baseURL:nil];
[alertView setValue:contents forKey:@"accessoryView"];
[alertView show];

另一方面,如果我将 that 的最后两行替换为 [self.view addSubview:contents];,那么我会在屏幕的左上角看到相同的第二个 HTML 视图,但这会 滚动。

【问题讨论】:

奇怪!我添加了UIWebView,它可以正常滚动。是不是这个webView的内容太短,导致不能滚动。让我们尝试在另一个项目中添加 UIWebView 并测试。 您是否验证了您尝试使用的 HTML 如果您在移动 safari 中运行它可以正常工作? 我尝试了几个不同的 HTML 文件,所有这些文件在浏览器中都可以正常显示。我的 UIWebView 似乎也喜欢它,并且可以很好地显示文件的顶部。我根本无法滚动它来查看后面的内容。如果我使字体更小或“缩放以适应”,那么我还可以看到更多(或全部)文件。 UIWebView 根据其内容大小滚动。因此,您的 webview 可能无法获得正确的内容大小。你可以发布一个 HTML 文件来检查吗?您还可以通过在滚动是否正常工作的同一网络视图中加载任何其他网站吗? 我尝试了许多不同的 HTML 文件。在真正的浏览器或 android 应用程序中滚动很好。我什至尝试了一个简单的 <p>X</p> 文件,重复字母 a-z。它只显示前几段,无法滚动。此外,滚动条“闪烁”时表示仅显示顶部。 【参考方案1】:

我已经解决了。首先,我尝试在我的 MainController 类中将其添加到 -viewDidLoad

UIWebView* contents = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 250, 250)];
[contents loadHTMLString:@"<html><head><title>FOO</title></head><body><p>A</p><p>B</p><p>C</p><p>D</p><p>E</p><p>F</p><p>G</p><p>H</p><p>I</p><p>J</p><p>K</p><p>L</p><p>M</p><p>N</p><p>O</p><p>P</p><p>Q</p><p>R</p><p>S</p><p>T</p><p>U</p><p>V</p><p>W</p><p>X</p><p>Y</p><p>Z</p></body></html>" baseURL:nil];
contents.backgroundColor = [UIColor redColor];
[self.view addSubview:contents];

它显示但不可滚动。我有一个 StartupController 来处理初始化应用程序并首先运行,所以我在那里添加了相同的代码。 这是可滚动的!啊哈!

我突然想到覆盖 MainView 的*** Google 地图 (GMSMapView) 可能会吞下滚动事件,但会传递点击事件。在场景中,我创建了一个***的普通/简单/空UIView,而不仅仅是一个地图视图,并让GMSMapView 成为它的全尺寸子级。现在,当我将视图添加到新的***(简单)视图时,它们是地图的兄弟而不是子视图,并且可以正确获取所有事件。

因此,我的UIWebView 现在可以滚动了。感谢大家的cmets和建议!几个月来断断续续地尝试不同的事情,终于弄明白了。

【讨论】:

如果有人知道如何使用 XCode trace 事件,请告诉我。也许那样我就能很快看到是什么吞噬了滚动事件。【参考方案2】:

请检查 Web 视图是否完全包含在其父视图的范围内(依此类推,直到视图层次结构)。一个简单的方法是设置一些背景颜色。可能您有一些不符合您预期的约束。

同样,所有父视图都支持用户交互。

编辑:我知道网络视图是完全可见的。但这并不意味着它包含在其父视图的范围内。如果父视图有 clipsToBounds=NO(我相信默认值),那么任何超出其边界的子视图都是可见的,但不会收到触摸。

【讨论】:

我在问题中明确表示视图是完全可见的。我尝试以多种方式展示它,包括通过故事板和编程方式,具有各种大小和边框。我还说在父视图中启用了用户交互,后者通过相邻的 UITableView 接受触摸事件来证明。 我明白 - 我看到了。但是,如果子视图包含在其父视图的边界之外(并且 clipsToBounds=NO,默认值...),它可能是完全可见的(但不接收触摸)。我会用这些信息更新我的答案。感谢您的反对。

以上是关于为啥 UIWebView 不滚动?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 UIWebView 不能正确滚动?

使用WKWebView替换UIWebView

检测项中的静态库是否使用UIWebView

IOS UIWebView添加Cookie值请求

IOS进阶之WKWebView

如何清除/禁用 UIWebView 的浏览历史记录