UIScrollView在触摸GADBannerView子视图时无法滚动

7
我有一个使用Google AdMob Ads SDK的项目。我想在主页上显示一些广告和其他按钮,其中一些按钮在屏幕下方。
我使用了UIScrollView,并在其中添加了几个DFP的GADBannerView以及按钮。广告可以正常加载,我可以点击广告和按钮,没有问题。
问题是当我尝试滚动滚动视图时。如果我开始触摸广告视图,滚动视图将无法滚动。如果我从其他地方开始触摸,如按钮或空白处,则滚动视图会正确滚动。似乎广告正在以某种方式控制触摸事件。
我尝试了各种修复方法,例如创建一个位于广告上方的透明UIView,但这不起作用,因为点击不会注册。
我尝试循环遍历GADBannerView的子视图,但所有子视图的类都似乎是AdMob专有或无法访问的。(GADWebView,_UIWebViewScrollView)
我甚至尝试将广告添加到UITableView中,以查看是否可以在那里滚动,但也没有成功。
我的视图控制器类非常大,所以如果您需要我发布一些代码,我可以创建一个演示问题的示例应用程序。现在的解决方法是使用HTML广告代码创建UIWebViews,而不是使用GADBannerView。我已经测试过这个方法,它可以工作,但我真的不想失去本机方法的功能。
是否有办法在您开始触摸GADBannerView时滚动UIScrollView并允许广告保持可点击性?
谢谢!
8个回答

9

这个问题可以通过子类化UIScrollView,符合UIGestureRecognizerDelegate协议,并从中返回YES来解决。

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

您不需要设置代理; UIScrollView已经默认设置为其手势识别器的代理。

这意味着您无需手动指定代理对象。


@SjoerdPerfors 找到了在UITableView上使其工作的解决方案吗? - Jay Q.
@JayQ。好的,我还没有看到它被弃用,所以如果 SwipeableBanner 类被删除了,我就不知道了。https://dev59.com/LWDVa4cB1Zd3GeqPh_Dq#20521939 - Sjoerd Perfors

3
问题在于GADBannerView使用的UIWebView中的手势识别器与GADBannerView中的自定义识别器之间存在冲突。 如果不通过子类化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;
                }
            }
        }
    }
}

那么您应该实现同时手势识别器委托来允许同时识别:

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

这可能不是最优雅的解决方案,但它可以在不需要子类化UIScrollView的情况下工作。 - jfuellert
现在我得到了一个可滚动的横幅而不是可滚动的表视图。 - Sjoerd Perfors
但现在广告无法点击了...那么将视图的userInteractionEnabled设置为NO有什么区别呢? - Zian Chen

2

我需要将上面两个答案结合起来:

   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;

    }

其中 bannerView_ 是一个 GADBannerView


2
对于DFP,您可以使用DFPSwipeableBannerView而不是DFPBannerView。不确定原始的GADBanner如何工作,但这应该是相同的。适用于UITableView。

有人知道我们现在应该怎么做吗?谷歌在修复错误版本中弃用了DFPSwipeableBannerView,甚至没有在发布说明中提到它。不是我有什么不满... - Sami Samhuri
@SamiSamhuri,你找到解决方案了吗? - Jay Q.
@JayQ。我现在只是使用DFPBannerView。它应该以相同的方式运作,并且对我来说工作得很好。如果他们当时提到了这一点,我就不会感到不满意了。 - Sami Samhuri
@SamiSamhuri 对不起,您是在说DFPBannerView在UITableView上滚动没有问题吗?我似乎无法让它正常工作。我正在使用最新的SDK。 - Jay Q.
@JayQ。在UITableView中它运行良好。某些广告存在问题。如果广告的大小超过我们的广告单元大小(300x250),则尝试在广告内部开始滚动会滚动广告而不是表视图。除此之外,它运行良好。如果您已经在滚动并滑动广告以继续滚动,则它可以正常工作。 - Sami Samhuri

2
我在尝试将DFPBannerView作为自定义单元格中contentView的子视图添加到表视图中时遇到了这个问题。
由于某种原因,将自定义单元格类中定义的IBOutlet与故事板中单元格中的视图连接起来会导致滚动开始工作。即使未使用该视图outlet,它也完全与横幅视图分开 - 即使从其父视图中删除该视图也可以使滚动行为正常工作。只是定义一个outlet并将其连接到某个东西就能解决问题。
我希望我能解释为什么会这样工作,但它仍然是iOS的一个谜。

0
我遇到了同样的问题,但决定采用更简单的解决方案。我发现只需禁用广告的Web视图反弹,就可以在触摸广告时使父滚动视图正常滚动。由于广告与Web视图大小相同,因此gestureRecognizer所做的唯一事情就是显示反弹行为。只需关闭它并保留当前的gestureRecognizer即可。
- (void)disableBannerBounce:(GADBannerView*)bannerView{
    for (UIWebView *webView in bannerView.subviews) {
        if ([webView isKindOfClass:[UIWebView class]]) {

            webView.scrollView.bounces = NO;     
        }
    }
}

0
我通过深入研究GADBannerView并将其Web浏览器视图手势的委托设置为我的视图,然后只需返回所有同时手势处理的YES来解决了这个问题。
id webBrowserView = [[[[[[adView subviews] firstObject] subviews] firstObject] subviews] firstObject];

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

然后在以下委托方法中只需返回“是”即可:

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

0

很遗憾,目前没有办法覆盖滚动手势但保留广告的触摸手势。GADBannerView本身需要控制其上的所有手势。也没有办法通过编程方式向GADBannerView发送点击事件,因此您也无法覆盖触摸行为。

我建议使用比您的UIScrollView小得多的广告,这样您就不必太担心在广告上滚动了。


我也是这么想的,但还是想问一下。谢谢你提供的信息。 - justin_713
3
实际上,这是可能的。请参见此帖子中Jacob Jenning的答案。 - Ellen Teapot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接