背景故事
我有一个 iPad 应用程序需要允许用户浏览图像组.每个组都布置在自己的垂直 UIScrollView(分页)中,因此用户可以上下滑动以查看每个图像.每组 UIScrollViews 都放置在单个(应用程序中仅存在一个)外部水平 UIScrollView(也分页)中.这效果很好....我可以上下滑动查看组中的图像,左右滑动可以转到下一个或上一个组.
Backstory
I have an iPad app that needs to allow the user to navigate through groups of images. Each group is laid out in its own vertical UIScrollView (paged) so the user can swipe up and down down to see each image. Each of the group UIScrollViews is placed in a single (only one exists in the app) outer horizontal UIScrollView (also paged). This works great.... I can swipe up and down to view the images in a group and swipe left and right to go to the next or previous group.
问题
当我需要为每个图像添加缩放时,问题就开始了.我通过将每个图像放在它自己的 UIScrollView 中来实现这一点.当图像被缩放时,我可以在图像周围平移,当我到达缩放图像的顶部或底部时,组的垂直 UIScrollView 页面按预期到下一个或上一个图像.不幸的是,当图像被缩放并且我平移到最左边或最右边时,外部水平滚动视图不会分页到下一组.
Problem
The problem started when I needed to add zooming for each image. I accomplished this by placing each image inside its own UIScrollView. When the image is zoomed I can pan around the image and when I get to the top or the bottom of the zoomed image the group's vertical UIScrollView pages to the next or previous image as expected. Unfortunately the outer horizontal scrollview will not page to the next group when the image is zoomed and I pan to the leftmost or rightmost edge.
有没有比三重嵌套 UIScrollViews 更好(更正确)的方法,或者我可以以某种方式将触摸转发到外部水平滚动视图?
Is there a better(more correct) approach than triple nesting UIScrollViews or can I somehow forward touches to the outer horizontal scrollview?
任何帮助或建议将不胜感激.
Any help or suggestions would be greatly appreciated.
希望我为时不晚,但我想我有办法解决你的问题.
hope i'm not too late but I think I have a solution for your problem.
在这里您可以找到一个 Xcode 项目,展示您的滚动视图设置、您的问题和建议的解决方案:https:///bitbucket.org/reydan/threescrollviews
Here you can find an Xcode project demonstrating the scrollview setup you have, your problem and the proposed solution: https://bitbucket.org/reydan/threescrollviews
基本上解决方案是在垂直滚动视图的 contentSize.width 上增加 1 个像素.当您平移到缩放图像的边缘时,这会强制垂直滚动视图滚动一点.它滚动一点,然后继续到下一个垂直滚动视图.
Basically the solution was to add 1 pixel to the contentSize.width of the vertical scrollviews. This forces the vertical scrollview to scroll a little when you pan to the edge of the zoomed image. It scrolls a little and then continues to the next vertical scrollview.
如果您下载项目,您会看到我在 viewDidLoad
方法中创建了一些滚动视图.在那里,我创建了一个包含 3 个垂直滚动视图的水平滚动视图,每个包含 5 个图像.每个图像实际上都封装在一个滚动视图中以启用每个图像的缩放.总共...三重嵌套滚动视图.
If you download the project you will see that I've created some scrollviews in the viewDidLoad
method. There, I create one horizontal scrollview containing 3 vertical scrollviews, each containing 5 images. Each image is actually incapsulated in a scrollview to enable per-image zooming. In total... triple nested scrollviews.
我还留下了一些彩色边框,以便我可以轻松查看每个滚动视图的滚动方式.
I've also left some colored borders so that I can easily see how each scrollview scrolls.
你会看到我已经用值 10 标记了每个图像滚动视图.这用于 - (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
委托方法的实现,我返回 nil
除非事件来自图像滚动视图之一.
You will see that I've tagged each image scrollview with value 10. This is used in the implementation of - (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
delegate method where I return nil
unless the event came from one of the image scrollviews.
如果您对我提出的项目有任何疑问,请随时提出.
If you have any questions about the project I made feel free to ask.
最后,我想说这种浏览方法对我来说有点古怪,因为我有时会朝不想要的方向滚动.通常我认为我垂直滑动手指只是为了发现滚动视图向左或向右移动,因为它解释了我的一些微小的水平移动.
In the end, I would like to say that this browsing method is a little quirky for me as I sometimes scroll in the unwanted direction. Often I think I flick my finger vertically only to find the scrollview going left or right because it interpreted some tiny horizontal movement I had.
我发现为水平和垂直移动启用分页的问题是滚动视图是方向锁定的,或者在我看来是这样.
The problem I found with paging enabled for both horizontal and vertical movement is that the scrollviews are direction-locked, or so it seemed to me.
今天我对这个问题进行了更深入的调查.以下是我的结论:
Today I've investigated the problem even more. These are my conclusions:
这不是缩放的问题,而是最里面的滚动视图中的内容比可见区域更大的问题(您可以通过缩放或简单地初始化大于边界的内容大小来尝试此操作).这可以在最里面的滚动视图内进行平移,并完全改变触摸事件的行为.
it's not a problem with zooming, it's a problem with having larger content in the innermost scrollview than the visible area(you can try this by zooming or simply initializing the content size larger than the bounds). This enables panning inside the inner-most scrollview and completely changes the behaviour of the touch events.
滚动视图标志的反弹会影响平移(拖动)手势到达内容边缘时的行为.如果 bounces=false
那么您的平移手势将停止在边缘,而不是将拖动事件沿链向上转发(因此不会滚动父滚动视图以向您显示其他图像).如果 bounces=true
那么,当您到达边缘并继续拖动时,事件将被转发到父滚动视图并且该滚动视图也将被拖动.但是,我发现弹跳时的拖动减少了大约 50% 的拖动距离.这也发生在照片应用中.
the bounce for a scrollview flag affects the behaviour of the panning(dragging) gesture when it reaches the edges of the content. If bounces=false
then your panning gesture will stop at the edge, not forwarding the drag event up the chain (and thus not scrolling the parent scrollviews to show you other images). If bounces=true
then, when you reach the edge and continue to drag the events will be forwarded to the parent scrollview and that scrollview will also be dragged. However, I've found that the dragging while bouncing reduces the distance dragged by aproximately 50%. This also happens in the Photos app.
如果您在最里面的滚动视图位于内容边缘时开始拖动,则滚动视图是智能的,会将所有事件转发到父滚动视图.
if you start the dragging while the innermost scrollview is at the edge of the content then the scrollview is smart and will forward all events to the parent scrollview.
由于某种原因,三重嵌套滚动视图是有问题的,因为在最内层滚动视图内平移时,事件根本不会在最顶部和中间滚动视图之间转发.我不知道为什么.
for some reason, triple nested scrollviews are problematic as the events are simply not forwarded between the topmost and middle scrollviews while panning inside the innermost scrollview. I have no idea why.
我的解决方案是内容大小 +1 像素,部分解决了问题.
My solution with that +1 pixel to the content size, partially solves the problem.
2013 年编辑
男孩,这些滚动视图是这个世界的东西:(
Boy, these scrollviews are something out of this world :(
经过一年多的搜索(开个玩笑……实际上是 2 天),我想我找到了一个很好的优雅解决方案来解决三重嵌套滚动视图.我在这里创建了一个测试项目:https://github.com/reydanro/TripleNestedScrollViews
After more than a year of searching (just kidding... it was actually 2 days) I think I found a good elegant solution to the triple nested scrollviews. I created a test project here: https://github.com/reydanro/TripleNestedScrollViews
在应用程序内部,有一个开关,您可以使用它来测试是否有修复.
Inside the app, there is a switch which you can use to test with/without the fix.
我在我的应用程序中使用的设置与这个问题有点不同.我有 1 个垂直分页滚动视图.在其中,我有多个水平分页滚动视图.在一些水平滚动视图中,我有另一个垂直分页滚动视图.
The setup I am using in my app is a little different than this question. I have 1 vertical paged scrollview. Inside it, I have multiple horizontal paged scrollviews. Inside some of the horizontal scrollviews I have another vertical paged scrollview.
如果没有修复,一旦您到达带有最内层滚动视图的页面,您几乎会被卡在那里,因为垂直滚动手势不会转发到最外层滚动.
Without the fix, once you get to the page with the inner-most scrollview you are pretty much stuck there as the vertical scrolling gestures are not forwarded to the outer-most scroll.
修复是您需要添加到最内层滚动视图的自定义 UIGestureRecognizer.此识别器跟随触摸事件,如果它检测到超出 contentArea 的拖动,那么它将暂时禁用滚动视图的其余识别器.这是我发现的使滚动视图将事件向上传递的唯一方法
The fix is a custom UIGestureRecognizer that you need to add to the inner-most scrollviews. This recognizer follows touch events and if it detects a drag beyond the contentArea, then it will temporarily disable the rest of the scrollview's recognizers. This is the only method I discovered to make the scrollview forward the events up the chain
手势识别器代码非常粗糙,自定义有限,但应该可以完成工作.目前我专注于我开发的应用程序,但会继续更新存储库.
The gesture recognizer code is very rough with limited customization but should get the job done. At the moment I am focused on the app I develop, but will continue to update the repository.
PS:我还没有测试过缩放会发生什么,但我看不出为什么这种方法不应该工作(或适应工作).
PS: I haven't tested what happens with zoom but I see no reason why this method should not work (or be adapted to work).
这篇关于三重嵌套 UIScrollView 分页问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!