• iOS开发中实现广告页的思路


    参考XHLaunchAd https://github.com/CoderZhuXH/XHLaunchAd

    温馨提示:由于有复制的代码,文章少长,建议在大屏上阅读,效果更佳!

    看代码

    1. +(XHLaunchAd *)imageAdWithImageAdConfiguration:(XHLaunchImageAdConfiguration *)imageAdconfiguration delegate:(id)delegate{
    2. XHLaunchAd *launchAd = [XHLaunchAd shareLaunchAd];
    3. if(delegate) launchAd.delegate = delegate;
    4. launchAd.imageAdConfiguration = imageAdconfiguration;
    5. return launchAd;
    6. }

    1. +(XHLaunchAd *)shareLaunchAd{
    2. static XHLaunchAd *instance = nil;
    3. static dispatch_once_t oneToken;
    4. dispatch_once(&oneToken,^{
    5. instance = [[XHLaunchAd alloc] init];
    6. });
    7. return instance;
    8. }

    1. - (instancetype)init{
    2. self = [super init];
    3. if (self) {
    4. XHWeakSelf
    5. [self setupLaunchAd];
    6. [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
    7. [self setupLaunchAdEnterForeground];
    8. }];
    9. [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
    10. [self removeOnly];
    11. }];
    12. [[NSNotificationCenter defaultCenter] addObserverForName:XHLaunchAdDetailPageWillShowNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
    13. weakSelf.detailPageShowing = YES;
    14. }];
    15. [[NSNotificationCenter defaultCenter] addObserverForName:XHLaunchAdDetailPageShowFinishNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
    16. weakSelf.detailPageShowing = NO;
    17. }];
    18. }
    19. return self;
    20. }

    1. -(void)setupLaunchAd{
    2. UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    3. window.rootViewController = [XHLaunchAdController new];
    4. window.rootViewController.view.backgroundColor = [UIColor clearColor];
    5. window.rootViewController.view.userInteractionEnabled = NO;
    6. window.windowLevel = UIWindowLevelStatusBar + 1;
    7. window.hidden = NO;
    8. window.alpha = 1;
    9. _window = window;
    10. /** 添加launchImageView */
    11. [_window addSubview:[[XHLaunchImageView alloc] initWithSourceType:_sourceType]];
    12. _window.backgroundColor = [UIColor redColor];
    13. }

    1. -(void)setImageAdConfiguration:(XHLaunchImageAdConfiguration *)imageAdConfiguration{
    2. _imageAdConfiguration = imageAdConfiguration;
    3. _launchAdType = XHLaunchAdTypeImage;
    4. [self setupImageAdForConfiguration:imageAdConfiguration];
    5. }

    1. /**图片*/
    2. -(void)setupImageAdForConfiguration:(XHLaunchImageAdConfiguration *)configuration{
    3. if(_window == nil) return;
    4. [self removeSubViewsExceptLaunchAdImageView];
    5. XHLaunchAdImageView *adImageView = [[XHLaunchAdImageView alloc] init];
    6. [_window addSubview:adImageView];
    7. /** frame */
    8. if(configuration.frame.size.width>0 && configuration.frame.size.height>0) adImageView.frame = configuration.frame;
    9. if(configuration.contentMode) adImageView.contentMode = configuration.contentMode;
    10. /** webImage */
    11. if(configuration.imageNameOrURLString.length && XHISURLString(configuration.imageNameOrURLString)){ // 网络图片
    12. [XHLaunchAdCache async_saveImageUrl:configuration.imageNameOrURLString]; // 磁盘保存图片地址
    13. /** 自设图片 */
    14. if ([self.delegate respondsToSelector:@selector(xhLaunchAd:launchAdImageView:URL:)]) { // 使用三方框架或自己加载网络图片
    15. [self.delegate xhLaunchAd:self launchAdImageView:adImageView URL:[NSURL URLWithString:configuration.imageNameOrURLString]];
    16. }else{
    17. if(!configuration.imageOption) configuration.imageOption = XHLaunchAdImageDefault;
    18. XHWeakSelf
    19. [adImageView xh_setImageWithURL:[NSURL URLWithString:configuration.imageNameOrURLString] placeholderImage:nil GIFImageCycleOnce:configuration.GIFImageCycleOnce options:configuration.imageOption GIFImageCycleOnceFinish:^{
    20. //GIF不循环,播放完成
    21. [[NSNotificationCenter defaultCenter] postNotificationName:XHLaunchAdGIFImageCycleOnceFinishNotification object:nil userInfo:@{@"imageNameOrURLString":configuration.imageNameOrURLString}];
    22. } completed:^(UIImage *image,NSData *imageData,NSError *error,NSURL *url){
    23. if(!error){
    24. #pragma clang diagnostic push
    25. #pragma clang diagnostic ignored"-Wdeprecated-declarations"
    26. if ([weakSelf.delegate respondsToSelector:@selector(xhLaunchAd:imageDownLoadFinish:)]) {
    27. [weakSelf.delegate xhLaunchAd:self imageDownLoadFinish:image];
    28. }
    29. #pragma clang diagnostic pop
    30. if ([weakSelf.delegate respondsToSelector:@selector(xhLaunchAd:imageDownLoadFinish:imageData:)]) {
    31. [weakSelf.delegate xhLaunchAd:self imageDownLoadFinish:image imageData:imageData];
    32. }
    33. }
    34. }];
    35. if(configuration.imageOption == XHLaunchAdImageCacheInBackground){
    36. /** 缓存中未有 */
    37. if(![XHLaunchAdCache checkImageInCacheWithURL:[NSURL URLWithString:configuration.imageNameOrURLString]]){
    38. [self removeAndAnimateDefault]; return; /** 完成显示 */
    39. }
    40. }
    41. }
    42. }else{ // 本地图片
    43. if(configuration.imageNameOrURLString.length){
    44. NSData *data = XHDataWithFileName(configuration.imageNameOrURLString);
    45. if(XHISGIFTypeWithData(data)){
    46. FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:data];
    47. adImageView.animatedImage = image;
    48. adImageView.image = nil;
    49. __weak typeof(adImageView) w_adImageView = adImageView;
    50. adImageView.loopCompletionBlock = ^(NSUInteger loopCountRemaining) {
    51. if(configuration.GIFImageCycleOnce){
    52. [w_adImageView stopAnimating];
    53. XHLaunchAdLog(@"GIF不循环,播放完成");
    54. [[NSNotificationCenter defaultCenter] postNotificationName:XHLaunchAdGIFImageCycleOnceFinishNotification object:@{@"imageNameOrURLString":configuration.imageNameOrURLString}];
    55. }
    56. };
    57. }else{
    58. adImageView.animatedImage = nil;
    59. adImageView.image = [UIImage imageWithData:data];
    60. }
    61. #pragma clang diagnostic push
    62. #pragma clang diagnostic ignored"-Wdeprecated-declarations"
    63. if ([self.delegate respondsToSelector:@selector(xhLaunchAd:imageDownLoadFinish:)]) {
    64. [self.delegate xhLaunchAd:self imageDownLoadFinish:[UIImage imageWithData:data]];
    65. }
    66. #pragma clang diagnostic pop
    67. }else{
    68. XHLaunchAdLog(@"未设置广告图片");
    69. }
    70. }
    71. /** skipButton */
    72. [self addSkipButtonForConfiguration:configuration];
    73. [self startSkipDispathTimer];
    74. /** customView */
    75. if(configuration.subViews.count>0) [self addSubViews:configuration.subViews];
    76. XHWeakSelf
    77. adImageView.click = ^(CGPoint point) {
    78. [weakSelf clickAndPoint:point];
    79. };
    80. }

    疑问

    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.用自己的方式加载图片

    1. /**
    2. 如果你想用SDWebImage等框架加载网络广告图片,请实现此代理,注意:实现此方法后,图片缓存将不受XHLaunchAd管理
    3. @param launchAd XHLaunchAd
    4. @param launchAdImageView launchAdImageView
    5. @param url 图片url
    6. */
    7. -(void)xhLaunchAd:(XHLaunchAd *)launchAd launchAdImageView:(UIImageView *)launchAdImageView URL:(NSURL *)url;

    实现该代理便能用我们自己的方式去加载图片,如使用YYWebImage去加载webp格式的图片。

    思路

    1.使用一个单例来加载广告页
    2.创建一个配置类对象,设置所需的一些配置,如:图片地址、图片位置、倒计时类型等,并把这个配置类赋值给单例的相应属性
    3.创建一个window,在该window上添加广告页

  • 相关阅读:
    HDLbits: Dualedge
    魔百和CM311-1A_YST、(YM)_安卓9_S905L3A_默认开启ADB_纯净精简语音_完美线刷包
    WPF控件3
    python考研志愿填报模拟系统vue
    NC17383 A Simple Problem with Integers
    Linux命令(91)之mv
    ipad分享软件的方法,iphone怎么分享给ipad
    Java WebSocket服务在多tomcat服务下怎么进行互通,websocket多服务负载均衡下怎么进行交互,websocket客户端调用实例
    【开题报告】基于SSM的水质资源标本管理系统的设计与实现
    cocosCreator获取手机剪切板内容
  • 原文地址:https://blog.csdn.net/lrbtony/article/details/126379458