包含 UIWebViews 的“无限 UIScrollView”

Posted

技术标签:

【中文标题】包含 UIWebViews 的“无限 UIScrollView”【英文标题】:"Infinite UIScrollView" containing UIWebViews 【发布时间】:2011-07-26 12:34:50 【问题描述】:

背景:

首先,背景。我通过使用宽度为三页(0、1 和 2)的 UIScrollView 创建了一个“无限滚动视图”,然后确保 UIScrollView 在不滚动时始终位于第 1 页的中心。当您滚动到第 0 页或第 2 页并且 UIScrollViewDelegate 感应到滚动结束时,所有三个页面的内容首先切换到您滚动的方向,然后 UIScrollView 立即移回第 1 页,模拟效果您可以继续滚动浏览无穷无尽的页面。

起初,我使用 UITextView 来显示每个页面的文本内容,但很快就想要在文本样式方面更加灵活。因此,我最终使用了一个 UIWebView,我在其中加载了一个 NSString,其中包含我希望显示的样式化 html 内容。这非常有效,正是我想要的样子。

问题:

自然,在 UIWebView 中加载、解析和显示一个简单的 HTML 页面比在 UITextView 中加载静态文本需要更长的时间。因此,当您向任何方向滚动时,滚动视图会自动向后移动并切换页面内容,您可以在新内容显示之前提示旧内容十分之一秒。

我的解决方案(不起作用):

我在文档中搜索了 UIWebViewDelegate ,发现页面加载完成时有一个事件。我把它连接起来这样做:

    用户从第 1 页滚动到第 2 页。 UIScrollViewDelegate 调用 scrollViewDidEndDecelerating,告诉第 1 页将其内容切换到当前在第 2 页显示的相同内容。 第1页的UIWebViewDelegate调用webViewDidFinishLoad,告诉UIScrollView回到第1页,然后切换第0页和第2页的内容。

在我看来,这可以解决这个问题,但显然这还不够。因此,我请你帮忙。有任何想法吗?可能值得一提的是,我在所有方法中都有 NSLog 并确保它们被调用。如果还有什么问题,我很乐意回答您的任何问题。

提前致谢!

包含 UIScrollView 的视图控制器:

    // Sense when the UIScrollView stops accelerating
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)sender 
        if(pScrollView.contentOffset.x > pScrollView.frame.size.width) 
            [self switchToNextPost];
         else if (pScrollView.contentOffset.x < pScrollView.frame.size.width) 
            [self switchToPreviousPost];
        
    

    // Update the currentPost variable and switch page 1
    - (void)switchToNextPost 
        [prefs setInteger:[[self getNextKey:nil] intValue] forKey:@"currentPost"];

        [self loadPostWithKey:[self getCurrentKey] atPage:[NSNumber numberWithInt:1] withViewController:currentPage];
    

    // Update the currentPost variable and switch page 1
    - (void)switchToPreviousPost 
        [prefs setInteger:[[self getPreviousKey:nil] intValue] forKey:@"currentPost"];

        [self loadPostWithKey:[self getCurrentKey] atPage:[NSNumber numberWithInt:1] withViewController:currentPage];
    

    // Custom delegate function. Scrolls UIScrollView to page 1 and then loads new content on page 1 and 3
    - (void)webViewFinishedLoading 
        [pScrollView scrollRectToVisible:CGRectMake(pScrollView.frame.size.width, 0, pScrollView.frame.size.width, pScrollView.frame.size.height) animated:NO];

        [self loadPostWithKey:[self getPreviousKey:nil] atPage:[NSNumber numberWithInt:0] withViewController:previousPage];
        [self loadPostWithKey:[self getNextKey:nil] atPage:[NSNumber numberWithInt:2] withViewController:nextPage];
    

子视图的视图控制器在 UIScrollView 中显示为单独的页面

    // The delegate shown in previous code
    - (void)webViewDidFinishLoad:(UIWebView *)webView 
        [[self delegate] webViewFinishedLoading];
    

【问题讨论】:

你好 Alexander 和 lukya,我也在实现同样的事情。但无法解决这个问题。所以你们中的任何人都可以帮助我。我在等你的回复。我迫切需要它。请通过任何教程或任何工作代码尽快帮助我。提前致谢。 【参考方案1】:

我认为你能做的是

    从一开始就用相关内容填充所有三个页面..(您可能已经这样做了)... 开始滚动时,下一个(或上一个)页面会在您滚动时显示.. 滚动完成后,将滚动内容视图移至中心,而不是更改每个 Web 视图中的文本,而是更改视图的框架,以便保留相关的 Web 视图(即用户滚动到的一个)在中间,另外两个在两边调整 更改两个 Web 视图(不可见)的内容,以便为下一次滚动移动做好准备。

在快速滚动的情况下这仍然会失败..但由于加载内容的滞后,我任何方法都会在那里归档(我认为) 因此,您可以将所有 Web 视图设为空白(不加载任何内容)并在快速滚动的情况下显示活动指示器..

【讨论】:

感谢您的回答!我其实一开始就想使用这种方法,但后来改变了主意。我最终没有使用它的原因是我想不出一个好方法来跟踪不同视图的位置。现在,我可以轻松地使用变量名 previousPost、currentPost 和 nextPost 来了解在哪个子视图中加载哪个帖子,但是当我开始移动它们时,我需要另一种方法来跟踪这一点。你会怎么做? 想出了一个解决方案来使用您的技术跟踪子视图。现在它完美无缺。再次感谢您的回答! 你好 Alexander 和 lukya,我也在实现同样的事情。但无法解决这个问题。所以你们中的任何人都可以帮助我。我在等你的回复。我迫切需要它。请通过任何教程或任何工作代码尽快帮助我。提前致谢。

以上是关于包含 UIWebViews 的“无限 UIScrollView”的主要内容,如果未能解决你的问题,请参考以下文章

自动布局:使用 UIWebViews 自定义 UIView 高度约束

使用 UIPageControl 在 UIWebViews 之间切换

YouTube 嵌入 UIWebViews 不再适用于 iOS

iOS 跨不同 UIWebViews 共享 cookie

将多个 UIWebViews 作为 UIImages 写入 PDF 文件

带有 uiwebviews 内存泄漏的基于页面的应用程序