【问题标题】:Triple Nested UIScrollView paging issue三重嵌套 UIScrollView 分页问题
【发布时间】:2012-01-04 00:31:42
【问题描述】:

背景故事
我有一个 iPad 应用程序需要允许用户浏览图像组。每个组都布置在自己的垂直 UIScrollView(分页)中,因此用户可以上下滑动以查看每个图像。每组 UIScrollViews 都放置在单个(应用程序中仅存在一个)外部水平 UIScrollView(也分页)中。这效果很好....我可以上下滑动查看组中的图像,左右滑动可以转到下一个或上一个组。

问题
当我需要为每个图像添加缩放时,问题就开始了。我通过将每个图像放在它自己的 UIScrollView 中来实现这一点。当图像缩放时,我可以在图像周围平移,当我到达缩放图像的顶部或底部时,组的垂直 UIScrollView 页面按预期转到下一个或上一个图像。不幸的是,当图像被缩放并且我平移到最左边或最右边时,外部水平滚动视图不会分页到下一组。

有没有比三重嵌套 UIScrollViews 更好(更正确)的方法,或者我可以以某种方式将触摸转发到外部水平滚动视图?

任何帮助或建议将不胜感激。

【问题讨论】:

    标签: ios ipad uiscrollview zooming


    【解决方案1】:

    希望我还不算太晚,但我想我有办法解决你的问题。

    在这里您可以找到一个 Xcode 项目,展示您的滚动视图设置、您的问题和建议的解决方案:https://bitbucket.org/reydan/threescrollviews

    基本上解决方案是在垂直滚动视图的 contentSize.width 上增加 1 个像素。当您平移到缩放图像的边缘时,这会强制垂直滚动视图滚动一点。它滚动一点,然后继续到下一个垂直滚动视图。

    如果您下载该项目,您会看到我在viewDidLoad 方法中创建了一些滚动视图。在那里,我创建了一个包含 3 个垂直滚动视图的水平滚动视图,每个包含 5 个图像。每个图像实际上都封装在一个滚动视图中以启用每个图像的缩放。总共...三重嵌套滚动视图。

    我还留下了一些彩色边框,以便我可以轻松查看每个滚动视图的滚动方式。

    • 洋红色 = 水平滚动视图
    • 白色 = 垂直滚动视图
    • 蓝色 = 图像滚动视图(包含图像并允许缩放的视图)
    • 红色 = UIImageView

    您将看到我已将每个图像滚动视图标记为值 10。这用于实现 - (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView 委托方法,除非事件来自图像滚动视图之一,否则我将返回 nil。

    如果您对我提出的项目有任何疑问,请随时提出。

    最后,我想说这种浏览方法对我来说有点古怪,因为我有时会朝不想要的方向滚动。通常我认为我垂直滑动手指只是为了发现滚动视图向左或向右移动,因为它解释了我的一些微小的水平移动。

    我发现为水平和垂直移动启用分页的问题是滚动视图是方向锁定的,或者在我看来是这样。

    编辑:

    今天我对这个问题进行了更深入的调查。以下是我的结论:

    • 这不是缩放的问题,而是最里面的滚动视图中的内容大于可见区域的问题(您可以通过缩放或简单地初始化大于边界的内容大小来尝试此操作)。这可以在最里面的滚动视图内进行平移,并完全改变触摸事件的行为。

    • 滚动视图标志的反弹会影响平移(拖动)手势到达内容边缘时的行为。如果bounces=false,那么您的平移手势将停止在边缘,而不是将拖动事件向上转发(因此不会滚动父滚动视图以向您显示其他图像)。如果bounces=true 那么,当您到达边缘并继续拖动时,事件将被转发到父滚动视图并且该滚动视图也将被拖动。但是,我发现弹跳时的拖动减少了大约 50% 的拖动距离。这也发生在照片应用中。

    • 如果您在最里面的滚动视图位于内容边缘时开始拖动,则滚动视图是智能的,会将所有事件转发到父滚动视图。

    • 出于某种原因,三重嵌套滚动视图存在问题,因为在最内层滚动视图内平移时,事件根本不会在最顶部和中间滚动视图之间转发。我不知道为什么。

    我的解决方案是内容大小 +1 像素,部分解决了问题。

    2013 年编辑

    男孩,这些滚动视图是这个世界的东西:(

    经过一年多的搜索(开个玩笑……实际上是 2 天),我想我找到了一个很好的优雅解决方案来解决三重嵌套滚动视图。 我在这里创建了一个测试项目: https://github.com/reydanro/TripleNestedScrollViews

    在应用程序内部,有一个开关,您可以使用它来测试是否有修复。

    我在我的应用程序中使用的设置与这个问题有点不同。我有 1 个垂直分页滚动视图。在其中,我有多个水平分页滚动视图。 在一些水平滚动视图中,我有另一个垂直分页滚动视图。

    如果不进行修复,一旦您到达具有最内层滚动视图的页面,您几乎会被卡在那里,因为垂直滚动手势不会转发到最外层滚动。

    修复是您需要添加到最内层滚动视图的自定义 UIGestureRecognizer。此识别器跟随触摸事件,如果它检测到超出 contentArea 的拖动,那么它将暂时禁用滚动视图的其余识别器。这是我发现的使滚动视图将事件向上传递的唯一方法

    手势识别器代码非常粗糙,自定义有限,但应该可以完成工作。目前我专注于我开发的应用程序,但会继续更新存储库。

    PS:我还没有测试过缩放会发生什么,但我看不出为什么这种方法不应该工作(或适应工作)。

    【讨论】:

    • 非常感谢您的调查!诀窍很酷 :) 然而,这个解决方案并没有提供非常重要的体验。请尝试以下操作:在 Photos.app 中打开任何图片并将其放大一点。然后向左拖动,你会看到下一张图片的一部分。现在运行测试项目并稍微放大图像,然后开始拖动。不幸的是,您不会在下一个垂直滚动视图中看到第一张图像。你知道如何解决它吗?再次感谢您的努力。
    • 嗨,你确定不是因为我的边界。我将提交一个新版本,删除所有这些调试边框。
    • 您好,我已经提交了一个新版本,在该版本中我删除了那些调试边框并将所有背景颜色替换为黑色。最后我明白了你的新问题是什么。如果拖动缩放的图像,如果到达边距,您将看不到它旁边的图像。您必须先抬起手指,然后再次拖动,将显示下一个图像。我的猜测是触摸响应链需要一些技巧。我会调查的。同时,您可以下载该项目的新版本。
    • 注意到一些有趣的事情。向上/向下工作正常。您开始拖动缩放的图像,它会在不抬起任何手指的情况下转到下一张图像(就像照片应用程序一样)。左/右的问题是左/右移动来自缩放滚动视图的第二个父级(水平滚动条)。可能有些触摸没有正确转发。
    • 是的,UIKit 没有通过触摸上一层。 Apple 工程师似乎只处理两个嵌套滚动视图作为特例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 2012-08-20
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    • 2021-11-25
    相关资源
    最近更新 更多