iOS广告分层展示预研
主流广告展示逻辑是不支持同时展示不同类型的广告,比如:banner和video。公司为了增加曝光量,要求可以同时展示banner和video。比如ironsource在展示video时,再展示banner会出现黑屏问题,导致无法继续后续操作。
1、固定展示viewcontroller
最简单的是加一层controller,在着手操作的时候发现一个很大的问题是点击的问题,比如:游戏内不能点击。
使用透传事件可以解决此问题
#import "KTMAdViewController.h"
@interface KTMAdBackgroundView : UIView
@end
@implementation KTMAdBackgroundView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
for (UIView *subView in self.subviews.reverseObjectEnumerator) {
CGPoint newPoint = [self convertPoint:point toView:subView];
if ([subView pointInside:newPoint withEvent:event]) {
return [super hitTest:point withEvent:event];
}
}
if ([[self.parentController nextResponder] isKindOfClass:UIViewController.class]) {
UIViewController *gameVC = (UIViewController *)[self.parentController nextResponder];
// NSLog(@"self.parentController.view %@",gameVC.view);
if ([gameVC isKindOfClass:UINavigationController.class]) { // Cocos2d Game
UINavigationController *gameNavVC = (UINavigationController *)gameVC;
return gameNavVC.topViewController.view;
} else { // Unity Game
return gameVC.view;
}
}
return nil;
}
- (UIViewController *)parentController {
UIResponder *responder = [self nextResponder];
while (responder) {
if ([responder isKindOfClass:[UIViewController class]]) {
return (UIViewController *)responder;
}
responder = [responder nextResponder];
}
return nil;
}
@end
@interface KTMAdViewController ()
@end
@implementation KTMAdViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
KTMAdBackgroundView *view = [[KTMAdBackgroundView alloc] initWithFrame:self.view.frame];
self.view = view;
}
@end
使用方式是,banner固定展示在这一层,banner有自动刷新机制,如果获取顶层controller还是会有层级问题。
遇到问题
1、需要处理unity、cocos等不同的引擎,需要做特殊的处理,对应用App不友好,不能使用。
2、自渲染插屏如果是addSubview的方式添加到controller,banner需要insert到最下层,不然展示结束关闭时,banner也会被关闭。特别说明:头条的nativeInterstitial会把所在展示controller上所有view一起移除。
2、2层展示controller
想到最初在接入Admob广告时,发现Admob的banner广告会展示在textWindow上,我就把研究方向定在分不同window展示,方案的依据是:
(1)UITextEffectsWindow
这是iOS8引入的一个新window,是键盘所在的window。它的windowLevel是10,高于UIWindowLevelNormal。
(2)UIRemoteKeyboardWindow
iOS9之后,新增了一个类型为 UIRemoteKeyboardWindow 的窗口用来显示键盘按钮。目前对这个研究还不是很多,以后有了新发现再与大家分享。
在使用过层中发现,UITextEffectsWindow、UIRemoteKeyboardWindow在unity导出的游戏中默认不会出现,特别是UIRemoteKeyboardWindow只有在键盘弹出时,才会出现,并且键盘消失,它也会一起消失,那就只能使用UITextEffectsWindow。
调出UITextEffectsWindow
在+ (void)applicationDidBecomeActive:(UIApplication *_Nullable)application
添加代码
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
UITextField *textfield = [[UITextField alloc] init];
[textfield becomeFirstResponder];
textfield.tag = 1000;
[[UIApplication sharedApplication].keyWindow.rootViewController.view addSubview:textfield];
});
//避免弹出键盘
+ (void)keyboardWillShow:(id)sender {
UITextField *view = (UITextField *) [[UIApplication sharedApplication].keyWindow.rootViewController.view viewWithTag:1000];
[view resignFirstResponder];
[view removeFromSuperview];
}
3、注意事项
在方案验证过程中,ironsource的广告在同时展示banner及video过程中,展示完成后点击关闭没有回调信息,直接黑屏。但ironsouce的video可以和其他广告的banner同时共存。