問題描述
背景故事
我有一個 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.
- 洋紅色 = 水平滾動視圖
- 白色 = 垂直滾動視圖
- 藍色 = 圖片滾動視圖(包含圖片并允許縮放的視圖)
- 紅色 = UIImageView
你會看到我已經用值 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模板網!