前不久有朋友需要一个启动广告的功能,我说网上有挺多的,他说,看的不是很理想。想让我写一个,于是乎,抽空写了一个,代码通俗易懂,简单的封装了一下,各种事件用block回调的,有俩种样式的广告,一种是全屏广告,另一种是下面露logo的,类似网页新闻的启动广告。依赖SDWebImage主要用来下载网络的广告图片,一般项目里面网络图片都用的这个框架,所以在此不做过多的阐述。下面让我们来看看我封装的过程,对于新手来说,可以学习一下这种封装的思想。

1.首先建一个继承View的LBLaunchImageAdView.h文件,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//  LBLaunchImageAdView.h
//  LBLaunchImageAd
//  Created by gold on 16/6/8.
//  Copyright  2016年 Bison. All rights reserved.
typedef enum {
     FullScreenAdType = 1, //全屏的广告
     LogoAdType = 0, //带logo的广告
}AdType;
#import <uikit uikit.h="">
#import "UIImageView+WebCache.h"
#define mainHeight      [[UIScreen mainScreen] bounds].size.height
#define mainWidth       [[UIScreen mainScreen] bounds].size.width
typedef void (^LBClick) (NSInteger tag);
@interface LBLaunchImageAdView : UIView
@property (strong, nonatomic) UIImageView *aDImgView;
@property (strong, nonatomic) UIWindow *window;
@property (assign, nonatomic) NSInteger adTime;  //倒计时总时长,默认6秒
@property (strong, nonatomic) UIButton *skipBtn;
@property (nonatomic, copy)LBClick clickBlock;
- (instancetype)initWithWindow:(UIWindow *)window andType:(NSInteger)type andImgUrl:(NSString *)url;
@end</uikit>

里面主要重写了init方法,init方法方便我们在调用封装的类初始化时传递一些参数,在此,我只传递了三个必要的参数,其他参数都用@property属性来调配,达到自己想要的效果,再有就是一个block的回调函数,主要处理各种事件。下面我们看看.m文件里面实现的部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//  LBLaunchImageAdView.m
//  LBLaunchImageAd
//  Created by gold on 16/6/8.
//  Copyright 2016年 Bison. All rights reserved.
#import "LBLaunchImageAdView.h"
@interface LBLaunchImageAdView()
{
     NSTimer *countDownTimer;
}
@property (strong, nonatomic) NSString *isClick;
@property (assign, nonatomic) NSInteger secondsCountDown;  //倒计时总时长
@end
@implementation LBLaunchImageAdView
- (instancetype)initWithWindow:(UIWindow *)window andType:(NSInteger)type andImgUrl:(NSString *)url
{
     self = [ super  init];
     if  (self) {
         self.window = window;
         _secondsCountDown = 0;
         [window makeKeyAndVisible];
         //获取启动图片
         CGSize viewSize = window.bounds.size;
         //横屏请设置成 @"Landscape"
         NSString *viewOrientation = @ "Portrait" ;
         NSString *launchImageName = nil;
         NSArray* imagesDict = [[[NSBundle mainBundle] infoDictionary] valueForKey:@ "UILaunchImages" ];
         for  (NSDictionary* dict  in  imagesDict)
         {
             CGSize imageSize = CGSizeFromString(dict[@ "UILaunchImageSize" ]);
             if  (CGSizeEqualToSize(imageSize, viewSize) && [viewOrientation isEqualToString:dict[@ "UILaunchImageOrientation" ]])
             {
                 launchImageName = dict[@ "UILaunchImageName" ];
             }
         }
         UIImage * launchImage = [UIImage imageNamed:launchImageName];
         self.backgroundColor = [UIColor colorWithPatternImage:launchImage];
         self.frame = CGRectMake(0, 0, mainWidth, mainHeight);
         if  (type == FullScreenAdType) {
             self.aDImgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, mainWidth, mainHeight)];
         } else {
             self.aDImgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, mainWidth, mainHeight - mainWidth/3)];
         }
         self.skipBtn = [UIButton buttonWithType:UIButtonTypeCustom];
         self.skipBtn.frame = CGRectMake(mainWidth - 70, 20, 60, 30);
         self.skipBtn.backgroundColor = [UIColor brownColor];
         self.skipBtn.titleLabel.font = [UIFont systemFontOfSize:14];
         [self.skipBtn addTarget:self action:@selector(skipBtnClick) forControlEvents:UIControlEventTouchUpInside];
         [self.aDImgView addSubview:self.skipBtn];
         UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.skipBtn.bounds byRoundingCorners:UIRectCornerBottomRight | UIRectCornerTopRight cornerRadii:CGSizeMake(15, 15)];
         CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
         maskLayer.frame = self.skipBtn.bounds;
         maskLayer.path = maskPath.CGPath;
         self.skipBtn.layer.mask = maskLayer;
         SDWebImageManager *manager = [SDWebImageManager sharedManager];
         [manager downloadImageWithURL:[NSURL URLWithString:url] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
         } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
             if  (image) {
                  [self.aDImgView setImage:[self imageCompressForWidth:image targetWidth:mainWidth]];
             }
         }];
         self.aDImgView.tag = 1101;
         self.aDImgView.backgroundColor = [UIColor redColor];
         [self addSubview:self.aDImgView];
         UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(activiTap:)];
         // 允许用户交互
         self.aDImgView.userInteractionEnabled = YES;
         [self.aDImgView addGestureRecognizer:tap];
         CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@ "opacity" ];
         opacityAnimation.duration = 0.8;
         opacityAnimation.fromValue = [NSNumber numberWithFloat:0.0];
         opacityAnimation.toValue = [NSNumber numberWithFloat:0.8];
         opacityAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
         [self.aDImgView.layer addAnimation:opacityAnimation forKey:@ "animateOpacity" ];
         countDownTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
         [self.window addSubview:self];
     }
     return  self;
}
#pragma mark - 点击广告
- (void)activiTap:(UITapGestureRecognizer*)recognizer{
     _isClick = @ "1" ;
     [self startcloseAnimation];
}
#pragma mark - 开启关闭动画
- (void)startcloseAnimation{
     CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@ "opacity" ];
     opacityAnimation.duration = 0.5;
     opacityAnimation.fromValue = [NSNumber numberWithFloat:1.0];
     opacityAnimation.toValue = [NSNumber numberWithFloat:0.3];
     opacityAnimation.removedOnCompletion = NO;
     opacityAnimation.fillMode = kCAFillModeForwards;
     [self.aDImgView.layer addAnimation:opacityAnimation forKey:@ "animateOpacity" ];
     [NSTimer scheduledTimerWithTimeInterval:opacityAnimation.duration
                                      target:self
                                    selector:@selector(closeAddImgAnimation)
                                    userInfo:nil
                                     repeats:NO];
}
- (void)skipBtnClick{
     _isClick = @ "2" ;
     [self startcloseAnimation];
}
#pragma mark - 关闭动画完成时处理事件
-(void)closeAddImgAnimation
{
     [countDownTimer invalidate];
     countDownTimer = nil;
     self.hidden = YES;
     self.aDImgView.hidden = YES;
     self.hidden = YES;
     if  ([_isClick integerValue] == 1) {
         if  (self.clickBlock) { //点击广告
             self.clickBlock(1100);
         }
     } else  if ([_isClick integerValue] == 2){
         if  (self.clickBlock) { //点击跳过
             self.clickBlock(1101);
         }
     } else {
         if  (self.clickBlock) { //点击跳过
             self.clickBlock(1102);
         }
     }
}
- (void)onTimer {
     if  (_adTime == 0) {
         _adTime = 6;
     }
     if  (_secondsCountDown < _adTime) {
         _secondsCountDown++;
         [self.skipBtn setTitle:[NSString stringWithFormat:@ "%ld | 跳过" ,_secondsCountDown] forState:UIControlStateNormal];
     } else {
         [countDownTimer invalidate];
         countDownTimer = nil;
         [self startcloseAnimation];
     }
}
#pragma mark - 指定宽度按比例缩放
- (UIImage *)imageCompressForWidth:(UIImage *)sourceImage targetWidth:(CGFloat)defineWidth {
     UIImage *newImage = nil;
     CGSize imageSize = sourceImage.size;
     CGFloat width = imageSize.width;
     CGFloat height = imageSize.height;
     CGFloat targetWidth = defineWidth;
     CGFloat targetHeight = height / (width / targetWidth);
     CGSize size = CGSizeMake(targetWidth, targetHeight);
     CGFloat scaleFactor = 0.0;
     CGFloat scaledWidth = targetWidth;
     CGFloat scaledHeight = targetHeight;
     CGPoint thumbnailPoint = CGPointMake(0.0, 0.0);
     if (CGSizeEqualToSize(imageSize, size) == NO){
         CGFloat widthFactor = targetWidth / width;
         CGFloat heightFactor = targetHeight / height;
         if (widthFactor > heightFactor){
             scaleFactor = widthFactor;
         }
         else {
             scaleFactor = heightFactor;
         }
         scaledWidth = width * scaleFactor;
         scaledHeight = height * scaleFactor;
         if (widthFactor > heightFactor){
             thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
         } else  if (widthFactor < heightFactor){
             thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
         }
     }
     //    UIGraphicsBeginImageContext(size);
     UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
     CGRect thumbnailRect = CGRectZero;
     thumbnailRect.origin = thumbnailPoint;
     thumbnailRect.size.width = scaledWidth;
     thumbnailRect.size.height = scaledHeight;
     [sourceImage drawInRect:thumbnailRect];
     newImage = UIGraphicsGetImageFromCurrentImageContext();
     if (newImage == nil){
         NSLog(@ "scale image fail" );
     }
     UIGraphicsEndImageContext();
     return  newImage;
}
@end

UI部分由于没有什么需要重用的地方,所以没有再另外抽取出来方法,全部放在init方法里面,显得有点臃肿。UI部分在此不做过多的阐述,里边主要运用了一个渐变的动画,利用CABasicAnimation中的opacity,有兴趣的朋友可以看看源码, 再有就是一个图片重构的方法,防止图片变形。

下面我们说下怎么集成我封装的这个功能吧,挺简单的,首先来看看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     /* FullScreenAdType 全屏广告
      * LogoAdType 带logo的广告类似网易广告,值得注意的是启动图片必须带logo图
      * ImgUrl  图片url
      */
     LBLaunchImageAdView * adView = [[LBLaunchImageAdView alloc]initWithWindow:self.window andType:LogoAdType andImgUrl:@ "http://www.uisheji.com/wp-content/uploads/2013/04/19/app-design-uisheji-ui-icon20121_55.jpg" ];
     //各种回调
     adView.clickBlock = ^(NSInteger tag){
         switch  (tag) {
             case  1100:{
                 NSLog(@ "点击广告回调" );
                 TestViewController *vc = [[TestViewController alloc]init];
                 vc.view.backgroundColor = [UIColor whiteColor];
                 [self.window.rootViewController presentViewController:vc animated:YES completion:^{
                 }];
             }
                 break ;
             case  1101:
                 NSLog(@ "点击跳过回调" );
                 break ;
             case  1102:
                 NSLog(@ "倒计时完成后的回调" );
                 break ;
             default :
                 break ;
         }
     };
     return  YES;
}

首先在AppDelegate.m导入头文件#import "LBLaunchImageAdView.h",然后在didFinishLaunchingWithOptions方法里面初始化一下,最后就是一些点击的回调事件了。到此,讲解完毕,最后丢上效果图和下载地址。

下载地址:https://github.com/AllLuckly/LBLaunchImageAd

解决iOS开发中App启动广告的功能相关推荐

  1. iOS开发有关app启动时的动态页面展示(非启动页面)

    很多APP启动的时候,需要动态的更换启动页面,可以在这个地方增添广告或者是将APP中新加入的一些活动信息等展示给用户.废话不多说,上代码: 一般都是在AppDelegate中的这个方法进行实现,当然这 ...

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

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

  3. iOS开发中解决第三方静态库符号冲突的终极方案

    iOS开发中解决第三方静态库符号冲突的终极方案 背景 在iOS开发的时候,经常会使用各种第三方静态库,这些库内部可能会打包了相同的第三方库.那么在链接的时候就会发生符号冲突. 例如:A厂商提供的lib ...

  4. IOS 开发中 Whose view is not in the window hierarchy 错误的解决办法

    在 IOS 开发当中经常碰到 whose view is not in the window hierarchy 的错误,该错误简单的说,是由于 "ViewController" ...

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

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

  6. iOS开发中的神兵利器

    苹果商店免费下载:https://itunes.apple.com/cn/app/id1209739676 网易云课程同名视频教程:http://study.163.com/course/course ...

  7. iOS开发中遇到的一些问题及解决方案【转载】

    iOS开发中遇到的一些问题及解决方案[转载] 2015-12-29 [385][scrollView不接受点击事件,是因为事件传递失败] // //  MyScrollView.m //  Creat ...

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

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

  9. iOS 开发中的多线程

    线程.进程 什么是线程.进程   有的人说进程就像是人的脑袋,线程就是脑袋上的头发~~.其实这么比方不算错,但是更简单的来说,用迅雷下载文件,迅雷这个程序就是一个进程,下载的文件就是一个线程,同时下载 ...

最新文章

  1. 同一天,数学和计算机界“诺奖”分别揭晓
  2. android 配置aspect_Android APP全面屏适配技术要点
  3. Android 中文 API (27) —— SeekBar.OnSeekBarChangeListener
  4. MySQL学习笔记(二):MyISAM 存储引擎
  5. graphql 有必要吗_您准备好观看GraphQL了吗?
  6. Oracle Database Appliance
  7. Linq中string转int的方法
  8. 高德地图画带箭头的线_模具装配图画成这样,那才真的叫标准!
  9. jdbc mysql url写法_MySQL第04篇:JDBC
  10. Leetcode每日一题:140.word-break-ii(单词拆分)
  11. 数字化方法基础(三)_导入本地模型
  12. ArcGIS Server大数据量地图服务影像缓存建立方法初探
  13. 图书期刊信息管理系统c语言,基于C语言的图书馆管理系统.doc
  14. 天线工作原理以及如何计算天线长度
  15. SpringBoot Spring Cloud项目学习汇总
  16. 如何使用python-如何用Python提取中文关键词?
  17. 柔顺控制 - 技术发展综述
  18. 品牌出海是机遇也是挑战
  19. 关于修改ant table选中行的背景色
  20. QByteArrary、QString、QSL使用注意事项

热门文章

  1. 所谓情商高,就是懂得好好说话
  2. 前端页面颜色选择器推荐
  3. 用空间状态法求解传教士和食人者问题
  4. 薅羊毛 京豆 全网最全脚本库 青龙面板 目前最新脚本库(11/7日更新)
  5. Arduino ESP8266自定义配置分区表
  6. 三星手機android6.01,台版三星Galaxy Note 5 升级Android 6.0有哪些变化
  7. 关于博客园CNBLOG美化
  8. 在VM7中安装Fedora 14
  9. Android 表情功能实现,封装面板方便使用
  10. jQuery使用ajax异步请求400解决方法