参考XHLaunchAd https://github.com/CoderZhuXH/XHLaunchAd
温馨提示:由于有复制的代码,文章少长,建议在大屏上阅读,效果更佳!
看代码
- +(XHLaunchAd *)imageAdWithImageAdConfiguration:(XHLaunchImageAdConfiguration *)imageAdconfiguration delegate:(id)delegate{
- XHLaunchAd *launchAd = [XHLaunchAd shareLaunchAd];
- if(delegate) launchAd.delegate = delegate;
- launchAd.imageAdConfiguration = imageAdconfiguration;
- return launchAd;
- }
- +(XHLaunchAd *)shareLaunchAd{
- static XHLaunchAd *instance = nil;
- static dispatch_once_t oneToken;
- dispatch_once(&oneToken,^{
- instance = [[XHLaunchAd alloc] init];
- });
- return instance;
- }
- - (instancetype)init{
- self = [super init];
- if (self) {
- XHWeakSelf
- [self setupLaunchAd];
- [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
- [self setupLaunchAdEnterForeground];
- }];
- [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
- [self removeOnly];
- }];
- [[NSNotificationCenter defaultCenter] addObserverForName:XHLaunchAdDetailPageWillShowNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
- weakSelf.detailPageShowing = YES;
- }];
- [[NSNotificationCenter defaultCenter] addObserverForName:XHLaunchAdDetailPageShowFinishNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
- weakSelf.detailPageShowing = NO;
- }];
- }
- return self;
- }
- -(void)setupLaunchAd{
- UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
- window.rootViewController = [XHLaunchAdController new];
- window.rootViewController.view.backgroundColor = [UIColor clearColor];
- window.rootViewController.view.userInteractionEnabled = NO;
- window.windowLevel = UIWindowLevelStatusBar + 1;
- window.hidden = NO;
- window.alpha = 1;
- _window = window;
- /** 添加launchImageView */
- [_window addSubview:[[XHLaunchImageView alloc] initWithSourceType:_sourceType]];
- _window.backgroundColor = [UIColor redColor];
- }
- -(void)setImageAdConfiguration:(XHLaunchImageAdConfiguration *)imageAdConfiguration{
- _imageAdConfiguration = imageAdConfiguration;
- _launchAdType = XHLaunchAdTypeImage;
- [self setupImageAdForConfiguration:imageAdConfiguration];
- }
- /**图片*/
- -(void)setupImageAdForConfiguration:(XHLaunchImageAdConfiguration *)configuration{
- if(_window == nil) return;
- [self removeSubViewsExceptLaunchAdImageView];
- XHLaunchAdImageView *adImageView = [[XHLaunchAdImageView alloc] init];
- [_window addSubview:adImageView];
- /** frame */
- if(configuration.frame.size.width>0 && configuration.frame.size.height>0) adImageView.frame = configuration.frame;
- if(configuration.contentMode) adImageView.contentMode = configuration.contentMode;
- /** webImage */
- if(configuration.imageNameOrURLString.length && XHISURLString(configuration.imageNameOrURLString)){ // 网络图片
- [XHLaunchAdCache async_saveImageUrl:configuration.imageNameOrURLString]; // 磁盘保存图片地址
- /** 自设图片 */
- if ([self.delegate respondsToSelector:@selector(xhLaunchAd:launchAdImageView:URL:)]) { // 使用三方框架或自己加载网络图片
- [self.delegate xhLaunchAd:self launchAdImageView:adImageView URL:[NSURL URLWithString:configuration.imageNameOrURLString]];
- }else{
- if(!configuration.imageOption) configuration.imageOption = XHLaunchAdImageDefault;
- XHWeakSelf
- [adImageView xh_setImageWithURL:[NSURL URLWithString:configuration.imageNameOrURLString] placeholderImage:nil GIFImageCycleOnce:configuration.GIFImageCycleOnce options:configuration.imageOption GIFImageCycleOnceFinish:^{
- //GIF不循环,播放完成
- [[NSNotificationCenter defaultCenter] postNotificationName:XHLaunchAdGIFImageCycleOnceFinishNotification object:nil userInfo:@{@"imageNameOrURLString":configuration.imageNameOrURLString}];
-
- } completed:^(UIImage *image,NSData *imageData,NSError *error,NSURL *url){
- if(!error){
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored"-Wdeprecated-declarations"
- if ([weakSelf.delegate respondsToSelector:@selector(xhLaunchAd:imageDownLoadFinish:)]) {
- [weakSelf.delegate xhLaunchAd:self imageDownLoadFinish:image];
- }
- #pragma clang diagnostic pop
- if ([weakSelf.delegate respondsToSelector:@selector(xhLaunchAd:imageDownLoadFinish:imageData:)]) {
- [weakSelf.delegate xhLaunchAd:self imageDownLoadFinish:image imageData:imageData];
- }
- }
- }];
- if(configuration.imageOption == XHLaunchAdImageCacheInBackground){
- /** 缓存中未有 */
- if(![XHLaunchAdCache checkImageInCacheWithURL:[NSURL URLWithString:configuration.imageNameOrURLString]]){
- [self removeAndAnimateDefault]; return; /** 完成显示 */
- }
- }
- }
- }else{ // 本地图片
- if(configuration.imageNameOrURLString.length){
- NSData *data = XHDataWithFileName(configuration.imageNameOrURLString);
- if(XHISGIFTypeWithData(data)){
- FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:data];
- adImageView.animatedImage = image;
- adImageView.image = nil;
- __weak typeof(adImageView) w_adImageView = adImageView;
- adImageView.loopCompletionBlock = ^(NSUInteger loopCountRemaining) {
- if(configuration.GIFImageCycleOnce){
- [w_adImageView stopAnimating];
- XHLaunchAdLog(@"GIF不循环,播放完成");
- [[NSNotificationCenter defaultCenter] postNotificationName:XHLaunchAdGIFImageCycleOnceFinishNotification object:@{@"imageNameOrURLString":configuration.imageNameOrURLString}];
- }
- };
- }else{
- adImageView.animatedImage = nil;
- adImageView.image = [UIImage imageWithData:data];
- }
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored"-Wdeprecated-declarations"
- if ([self.delegate respondsToSelector:@selector(xhLaunchAd:imageDownLoadFinish:)]) {
- [self.delegate xhLaunchAd:self imageDownLoadFinish:[UIImage imageWithData:data]];
- }
- #pragma clang diagnostic pop
- }else{
- XHLaunchAdLog(@"未设置广告图片");
- }
- }
- /** skipButton */
- [self addSkipButtonForConfiguration:configuration];
- [self startSkipDispathTimer];
- /** customView */
- if(configuration.subViews.count>0) [self addSubViews:configuration.subViews];
- XHWeakSelf
- adImageView.click = ^(CGPoint point) {
- [weakSelf clickAndPoint:point];
- };
- }
疑问
1.XH中的window是怎么显示的?
设置了UIWindowLevelStatusBar属性
window.windowLevel = UIWindowLevelStatusBar + 1;
创建的window不用添加到任何控件上,创建完后就自动添加到window上了,但要想优先显示windowLevel 必须大于等于当前的window level 才会展示在上层。
[[UIApplication sharedApplication] keyWindow]获取正在显示的UIWindow是极其不准确的
销毁window的正确方式:
window.hidden = YES;
window = nil;
(注:iOS之后使用了SceneDelegate需要进行适配 https://www.jianshu.com/p/60bab1258efc)
自定义
1.用自己的方式加载图片
- /**
- 如果你想用SDWebImage等框架加载网络广告图片,请实现此代理,注意:实现此方法后,图片缓存将不受XHLaunchAd管理
- @param launchAd XHLaunchAd
- @param launchAdImageView launchAdImageView
- @param url 图片url
- */
- -(void)xhLaunchAd:(XHLaunchAd *)launchAd launchAdImageView:(UIImageView *)launchAdImageView URL:(NSURL *)url;
实现该代理便能用我们自己的方式去加载图片,如使用YYWebImage去加载webp格式的图片。
思路
1.使用一个单例来加载广告页
2.创建一个配置类对象,设置所需的一些配置,如:图片地址、图片位置、倒计时类型等,并把这个配置类赋值给单例的相应属性
3.创建一个window,在该window上添加广告页