简体   繁体   English

触摸GADBannerView子视图时,UIScrollView不会滚动

[英]UIScrollView doesn't scroll when touching GADBannerView subview

I have a project that uses the Google AdMob Ads SDK. 我有一个使用Google AdMob广告SDK的项目。 I'm trying to show a few ads on the homepage along with some other buttons, some of which are below the screen. 我试图在主页上显示一些广告以及其他一些按钮,其中一些按钮位于屏幕下方。

I've used a UIScrollView and added a few GADBannerViews from DFP inside as well the buttons. 我使用了UIScrollView并在DFP中添加了一些GADBannerViews以及按钮。 The ads load just fine and I can click on the ads and buttons with no problem. 广告加载得很好,我可以毫无问题地点击广告和按钮。

The problem is when I try to scroll the scroll view. 问题是当我尝试滚动滚动视图时。 If I start touching on the ad view, the scroll view will not scroll. 如果我开始触摸广告视图,滚动视图将不会滚动。 If I start touching anywhere else, like a button or a blank space, the scroll view scrolls properly. 如果我开始触摸其他任何地方,例如按钮或空白区域,滚动视图会正确滚动。 It seems that the ad is somehow taking control of the touch events. 似乎广告以某种方式控制了触摸事件。

I've tried all sorts of fixes such as creating a transparent UIView above the ads, which didn't work because the taps would not register. 我尝试过各种各样的修复工具,例如在广告上方创建一个透明的UIView,但由于水龙头无法注册,因此无效。

I've tried looping through the subviews of the GADBannerView but all the subviews' classes seem proprietary to AdMob or inaccessible. 我已经尝试循环浏览GADBannerView的子视图,但所有子视图的类似乎都是AdMob专有的或无法访问的。 (GADWebView, _UIWebViewScrollView) (GADWebView,_UIWebViewScrollView)

I even tried adding the ad to a UITableView to see if it would scroll there, but it did not work either. 我甚至尝试将广告添加到UITableView以查看它是否会在那里滚动,但它也不起作用。

My view controller class is quite large so if you need me to post some code, I can create a sample app to demonstrate the problem. 我的视图控制器类非常大,所以如果你需要我发布一些代码,我可以创建一个示例应用程序来演示问题。 A workaround for now is to create UIWebViews with the HTML ad code inside instead of using the GADBannerView. 目前的解决方法是使用HTML广告代码创建UIWebViews,而不是使用GADBannerView。 I've tested this and it works, but I really don't want to lose the functionality of the native method. 我已经测试了它并且它可以工作,但我真的不想失去原生方法的功能。

Is there any way to scroll a UIScrollView if you start touching on the GADBannerView and allow the ad to remain clickable? 如果您开始触摸GADBannerView并允许广告保持可点击,有没有办法滚动UIScrollView?

Thanks! 谢谢!

This issue can be resolved by subclassing UIScrollView, conforming to the the UIGestureRecognizerDelegate protocol, and returning YES from 可以通过继承UIScrollView来解决此问题,符合UIGestureRecognizerDelegate协议,并从中返回YES

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

You shouldn't need to set the delegate; 您不需要设置委托; UIScrollView is already set as the delegate of it's gesture recognizers by default. 默认情况下,UIScrollView已设置为其手势识别器的委托。

The problem is a conflict between the gesture recognizer in the UIWebView used by GADBannerView and a custom recognizer in GADBAnnerView. 问题是GADBannerView使用的UIWebView中的手势识别器与GADBAnnerView中的自定义识别器之间存在冲突。 Without subclassing UIScrollView and changing the gesture recognizer delegate, you can remove this gesture recognizer and set your object as delegate for custom recognizer with this: 如果没有子类化UIScrollView并更改手势识别器委托,您可以删除此手势识别器并将对象设置为自定义识别器的委托,使用:

- (void)preventBannerCaptureTouch:(GADBannerView*)bannerView
{
    for (UIWebView *webView in bannerView.subviews) {
        if ([webView isKindOfClass:[UIWebView class]]) {

            for (UIGestureRecognizer *gestureRecognizer in webView.gestureRecognizers) {
                if ([gestureRecognizer isKindOfClass:NSClassFromString(@"GADImpressionTicketGestureRecognizer")]) {
                    gestureRecognizer.delegate = self;
                }
            }

            for (id view in [[[webView subviews] firstObject] subviews]) {
                if ([view isKindOfClass:NSClassFromString(@"UIWebBrowserView")]) {
                    for (UIGestureRecognizer *recognizer in [view gestureRecognizers]) {
                        if ([recognizer isKindOfClass:NSClassFromString(@"UIWebTouchEventsGestureRecognizer")]) {
                            [view removeGestureRecognizer:recognizer];
                        }
                    }
                    return;
                }
            }
        }
    }
}

Then you should implement the simultaneous gesture recognizer delegate to allow simultaneously recognise: 然后你应该实现同步手势识别器委托,以允许同时识别:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

For DFP you can use a DFPSwipeableBannerView instead of a DFPBannerView. 对于DFP,您可以使用DFPSwipeableBannerView而不是DFPBannerView。 Not sure how the orignal GADBanner works tho, but this should be the same. 不确定原始GADBanner是如何工作的,但这应该是一样的。 Works in UITableView. 适用于UITableView。

I had to combine two of the answers above: 我必须结合上面的两个答案:

   for (UIWebView *webView in bannerView_.subviews) {
        if ([webView isKindOfClass:[UIWebView class]]) {
            adView = webView;
        }

        for (id view in [[[webView subviews] firstObject] subviews]) {
            if ([view isKindOfClass:NSClassFromString(@"UIWebBrowserView")]) {
                for (UIGestureRecognizer *recognizer in [view gestureRecognizers]) {
                    if ([recognizer isKindOfClass:NSClassFromString(@"UIWebTouchEventsGestureRecognizer")]) {
                        [view removeGestureRecognizer:recognizer];
                    }
                }
            }
        }
        webView.scrollView.scrollEnabled = NO;
        webView.scrollView.bounces = NO;

    }

Where bannerView_ is a GADBannerView 其中bannerView_是GADBannerView

I ran into this issue when trying to add a DFPBannerView as a subview of the contentView of a custom cell in a table view. 尝试在表格视图中添加DFPBannerView作为自定义单元格的contentView的子视图时,我遇到了此问题。

For some reason, connecting an IBOutlet defined in my custom cell class to a view in the cell in my storyboard caused the scrolling to start working. 出于某种原因,将我的自定义单元格类中定义的IBOutlet连接到故事板中单元格中的视图会导致滚动开始工作。 The view outlet wasn't even being used, and was completely separate from the banner view - even removing it from its superview allowed the scrolling behaviour to work. 视图插座甚至没有被使用,并且与横幅视图完全分离 - 即使将其从超级视图中移除也允许滚动行为起作用。 Just having an outlet defined and connected to something did the trick. 只是定义了一个插座并连接到某个东西就可以了。

I wish I could explain why this works, but it remains an iOS mystery. 我希望我能解释为什么这样有效,但它仍然是iOS之谜。

I solved this by digging down into the GADBannerView and setting the delegate for its web browser view gestures to my own view and then just returning YES for all simultaneous gesture handling: 我通过深入研究GADBannerView并将其Web浏览器视图手势的委托设置为我自己的视图来解决这个问题,然后只返回YES以进行所有同步手势处理:

id webBrowserView = [[[[[[adView subviews] firstObject] subviews] firstObject] subviews] firstObject];

for (UIGestureRecognizer *gestureRecognizer in [webBrowserView gestureRecognizers])
{
    [gestureRecognizer setDelegate:self];
}

Then just return yes in the following delegate method: 然后在以下委托方法中返回yes:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

I ran into the same issue, but decided on a simpler solution. 我遇到了同样的问题,但决定采用更简单的解决方案。 I found that just disabling the ad's web view bounce back allowed the parent scrollview to scroll properly when the ad was touched. 我发现只是禁用广告的网络视图反弹,允许父级滚动视图在触摸广告时正确滚动。 Since the ad is the same size as the webview, the only thing the gestureRecognizer was doing was showing the bounce back behavior. 由于广告与webview的大小相同,因此gestureRecognizer唯一要做的就是显示退回行为。 Just had to turn that off and left the current gestureRecognizer in place. 只需将其关闭并将当前的gestureRecognizer保留在原位。

- (void)disableBannerBounce:(GADBannerView*)bannerView{
    for (UIWebView *webView in bannerView.subviews) {
        if ([webView isKindOfClass:[UIWebView class]]) {

            webView.scrollView.bounces = NO;     
        }
    }
}

Unfortunately there is not a not a way to override the scrolling gesture but retain the touch gesture for the ad. 不幸的是,没有办法覆盖滚动手势但保留广告的触摸手势。 The GADBannerView itself needs to control all of the gestures on itself. GADBannerView本身需要控制自己的所有手势。 There is also no way to programmatically send a click to the GADBannerView either, so you can't override the touch behavior either. 也无法以编程方式向GADBannerView发送单击,因此您也无法覆盖触摸行为。

I would recommend using ads that are much smaller than your UIScrollView, so you don't have to worry too much about scrolling over an ad. 我建议使用比UIScrollView小得多的广告,这样您就不必过于担心滚动广告了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM