Passing swipe touches from UIView to underlying UIScrollView for proper scrolling

爱⌒轻易说出口 提交于 2019-12-05 07:45:59

Here's an easier solutions that worked well for me:

In the OverlayView (the view on top of UIScrollView), make the width and height both 0 (so that the view is no longer technically on top of the scrollview) and set clipsToBounds = NO (so that the contents of the OverlayView still show up on top of the scrollview). It worked like a charm for me.

 self.OverlayView.clipsToBounds = NO;
 CGRect frame = self.OverlayView.frame;
 self.OverlayView.frame = CGRectMake(frame.origin.x, frame.origin.y, 0, 0);

Note that if OverlayView contains interactive controls (like the button above) then they will no longer work. You'll need to move it into it's own view above the UIScrollView.

How about, at runtime in viewDidLoad you take the buttons out of the container view and place them in the view as subviews directly (and get rid of the container view)? Then there's no container view to intercept swipes but you can still use a view to group things in IB.

Also potentially you could put the container view in as a subview of the scroll view instead, and in the scroll view delegate keep re-positioning the view whenever the user scrolls. That would seem to have a high potential for being jittery but may be worth a try.

Also if the containing view is a visual container and you need to see it, you could instead use a CALayer that was placed in the superview on top of the CALayer for rendering the scroll view, since CALayers have nothing to do with input and would not each touches.

Frane Poljak

You should subclass UIScrollView and override the touchesShouldCancelInContentView: method

-(BOOL)touchesShouldCancelInContentView:(UIView *)view
{

    if ([view isKindOfClass:[UIButton class]]) {//or whatever class you want to be able to scroll in
        return YES;
    }

    if ([view isKindOfClass:[UIControl class]]) {
        return NO;
    }

    return YES;
}

I needed to so something similar and after some research and reading through Apple's documentation, I created this really simple and safe open source library that will solve your (MobileJoel) problem. The demo project uses a scrollview so it directly relates:
https://github.com/natrosoft/NATouchThroughView

So your view hierarchy would look like this:

UIView (MainView: 320x460)    
. .UIScrollView (ScrollView: 320x460)
. .UIView (OverlayView: 320x40)  --> change this view to class NARootTouchThroughView in I.B.
. . . .UIView (transparent UIView that you change to class NATouchThroughView in I.B.)
. . . .UIButton (ArbitraryButton1)
. . . .UILabel (ArbitraryLabel1)
. . . .UILabel (ArbitraryLabel2)

So basically your overlay view will forward its touches below it which will then get received by the UIScrollview. If your UILabels are huge and are intercepting touches, then place another NATouchThroughView on top of them so that the final result looks like this:

UIView (MainView: 320x460)    
. .UIScrollView (ScrollView: 320x460)
. .NARootTouchThroughView (OverlayView: 320x40)
. . . .NATouchThroughView (transparent)
. . . .UIButton (ArbitraryButton1)
. . . .UILabel (ArbitraryLabel1)
. . . .UILabel (ArbitraryLabel2)
. . . .NATouchThroughView (transparent and covers the labels but not the UIButton)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!