参考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 popif ([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];XHWeakSelfadImageView.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上添加广告页

iOS开发中实现广告页的思路相关推荐

  1. iOS开发中的Web应用概述

    为了更好的阅读体验,建议阅读原文 插播广告 -- 几十行代码完成资讯类App多种形式内容页 HybridPageKit :一个针对资讯类App高性能.易扩展.组件化的通用内容页实现框架. 想和我一起全 ...

  2. iOS开发中的神兵利器 [实战系列]-李发展-专题视频课程

    iOS开发中的神兵利器 [实战系列]-11758人已学习 课程介绍         - 140节课程讲解GitHub中近百个过千star的iOS热门开源项目 - 市面上唯一大规模讲解热门的iOS开源项 ...

  3. ios 开发中 动态库 与静态库的区别

    使用静态库的好处 1,模块化,分工合作 2,避免少量改动经常导致大量的重复编译连接 3,也可以重用,注意不是共享使用 动态库使用有如下好处: 1使用动态库,可以将最终可执行文件体积缩小 2使用动态库, ...

  4. 浅谈iOS 开发中的界面通信

    在任何的软件开发中都离不开界面与界面之间的通信,界面通信的最直接的方法就是界面传值. 在开发过程中我们在页面传值时我们通常使用的方法有:属性传值法,block传值法,代理传值法,以及单例传值法,通知传 ...

  5. ios加载本地html懒加载图片方案,IOS开发中加载大量网络图片优化方法

    IOS开发中加载大量网络图片如何优化 1.概述 在IOS下通过URL读一张网络图片并不像其他编程语言那样可以直接把图片路径放到图片路径的位置就ok,而是需要我们通过一段类似流的方式去加载网络图片,接着 ...

  6. Android开发固定app图标大小,Android和IOS开发图标、启动页尺寸

    最近项目在做android和ios的项目,设计师让我给出图标的尺寸,于是查了一下尺寸. 一.开发中的实际情况: 第一步:产品经理和UI设计师制定好UI规范,然后开始做图标做颜色做尺寸等一系列和APP界 ...

  7. 如何深入理解 iOS 开发中的锁?

    摘要 本文的目的不是介绍 iOS 中各种锁如何使用,一方面笔者没有大量的实战经验,另一方面这样的文章相当多,比如 iOS中保证线程安全的几种方式与性能对比.iOS 常见知识点(三):Lock.本文也不 ...

  8. 理解:iOS开发中锁的实现原理

    摘要 本文的目的不是介绍 iOS 中各种锁如何使用,一方面笔者没有大量的实战经验,另一方面这样的文章相当多,比如 iOS中保证线程安全的几种方式与性能对比.iOS 常见知识点(三):Lock.本文也不 ...

  9. 深入理解 iOS 开发中的锁

    深入理解 iOS 开发中的锁 摘要 本文的目的不是介绍 iOS 中各种锁如何使用,一方面笔者没有大量的实战经验,另一方面这样的文章相当多,比如 iOS中保证线程安全的几种方式与性能对比.iOS 常见知 ...

最新文章

  1. vw实现移动端自适应页面
  2. 《数据科学:R语言实现》——2.5 使用Excel文件
  3. 【python数据挖掘课程】十九.鸢尾花数据集可视化、线性回归、决策树花样分析
  4. ubuntu11.10 samba服务器配置
  5. idea @Autowired 注入爆红(无法注入)
  6. TS对象中的实例属性和静态属性
  7. java如何添加进程_如何创建一个进程,如何进程调用进程
  8. ftp服务器复制粘贴文件夹,ftp服务器复制粘贴文件夹
  9. 等级保护2.0常见问题集
  10. python刷b站教程_【Python】【学习资源】B站上的Python学习资源
  11. Android 使用RxJava实现一个发布/订阅事件总线
  12. Landsat卫星MSS/TM/ETM数据(转自ESRI社区)(二)
  13. matlab s函数z变换,Matlab符号计算——s函数转z函数
  14. PyTorch搭建ShuffleNet
  15. 深入理解socket中的recv函数和send函数
  16. RuntimeError:The size of tensor a (100) must match the size of tensor b (12800) at non-singleton di
  17. UVA - 10106 Product
  18. 嵌入式电子钢琴游戏开发设计
  19. java中是什么意思_java中@什么意思
  20. sparkStreaming常见问题

热门文章

  1. 华为云服务器如何搭建微信公众号后台-收发文本信息?
  2. 魔众企业官网系统 v4.5.0 后台菜单快捷搜索,组件显示优化
  3. ORACLE SUBSTR函数和INSTR函数的结合
  4. 阿里云ECS大测评【免费领阿里云套餐~】
  5. 代码格式化工具Astyle的使用
  6. HEVC intra和inter码率控制的不同
  7. 操作系统实验:读者写者问题
  8. Go time 时间的各种格式转换
  9. Excel拼接字符串技巧
  10. 【SQLite】SqlLite简介