开发者

Nested UIScrollView won't scroll when outter view is zoomed

I'm having quite a problem here when nesting UIScrollViews.

I have an outter paged scroll view, that does paged scrolling with it's UIScrollView subviews. These subviews contain a subview that have a CALayer with a big image. Whenever is needed this CALayer subviews can be have small scrollview added to them that act as small picture galleries. These galleries have their own viewcontroller called SlideViewController.

view

|

v

mainScrollView

|

v

UIScrollView (page)

|

v view with CALayer

|

v

ScrollView like gallery.

Everything works like a charm until the ipad is rotated to landscape and the page scroll view is zoomed a 33%.

All of the subviews are in their place. their bounds are correct, so as their frame. The thing is that when I swipe over the little galleries they don't scroll any more. The big page does. I've tried setting canCancelContentTouches to NO to all of the involved scrollviews.

I also subclassed the gallery scroll view to get a grip on the touchesEnded/began/cancelled and try to disable the super view scrolling from there with no success.

I tried to set the galleries as a first responder when I called init on them. With no further results.

Now I can scroll the galleries only if I put my finger for a while on them, so no gesture recognizer steals the swipe from them, and then scroll gently to the next picture of the gallery.

If I swipe normally, sometimes the big outter scrollview would steal the swipe and change the page, and sometimes the little gallery would catch it first.

this only happens when the scrollview containing the CA layer开发者_运维百科 (the page) is zoomed otherwise works amazingly great with no issues what so ever.

Am I screwing the UIResponder chain? How could I fix this?

I could paste you some code snippets, but this involves a handful of classes, that I don't know which ones could be of use or not.

Thanks in advance


I'll answer my own question just in case someone comes across this.

Firstly READ ---> this

Secondly what's going on right now is that the outter and inner scrollviews are struggling for the touch events being dispatched everytime you touch the screen. Since gesture recognizers like swipe recognizers take some time to recognize a swipe subviews of the outter view can catch the touches in the meantime, that causes that when you do the scrolling in the inner views some times it works and some times doesn't.

What I did was to subclass the views involved in the responder chain. Not all of them. just the inner-most and the outter-most which is actually the first responder.

In the first responder subclass (in my case is an UIView) override hit test. I got the code snippet and the idea from this question: How to steal touches from UIScrollView?

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView* result = [super hitTest:point withEvent:event];

    if ([result.superview isKindOfClass:[SlideView class]])
    {
        self.scrollEnabled = NO;
    }
    else 
    {
        self.scrollEnabled = YES;    
    }
    return result;
}

WHY? Because you want to disable scrolling from the outter views. That's the way it's swipe recognizers will be disabled and will leave your inner scrollview alone and free to grab the touches whenever it feels like it. This also contributes making scrolling more accurate for the user.

Well. Good luck. I'm going to commit this. ;-)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜