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

1.首先建一个继承View的LBLaunchImageAdView

.H文件 代码如下:

//

//  LBLaunchImageAdView.h

//  LBLaunchImageAd

//  技术交流群:534926022(免费) 511040024(0.8/人付费)

//  Created by gold on 16/6/8.

//  Copyright © 2016年 Bison. All rights reserved.

//  iOS开发学习app下载https://itunes.apple.com/cn/app/it-blog-for-ios-developers/id1067787090?mt=8

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

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

//

//  LBLaunchImageAdView.m

//  LBLaunchImageAd

//  技术交流群:534926022(免费) 511040024(0.8/人付费)

//  Created by gold on 16/6/8.

//  Copyright © 2016年 Bison. All rights reserved.

//  iOS开发学习app下载https://itunes.apple.com/cn/app/it-blog-for-ios-developers/id1067787090?mt=8

#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,有兴趣的朋友可以看看源码, 再有就是一个图片重构的方法,防止图片变形。

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

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

动图

下载地址

https://github.com/AllLuckly/LBLaunchImageAd

分分钟解决iOS开发中App启动广告的功能的更多相关文章

  1. ios开发中APP底部上滑不能调出如WiFi、蓝牙、播放等的设置页面的解决的方法

    在开发的APP中我们通常通过手动底部上滑来调出WiFi.蓝牙.飞行模式等的设置页面.有时我们开发的APP无法调出. 解决的方法: 进入iPhone "设置" --> &quo ...

  2. ios UIApplocation 中APP启动方式

    iOS app启动的方式有哪些: 自己启动(用户手动点击启动) urlscheme启动(关于urlScheme的详解)http://www.cnblogs.com/sunfuyou/p/6183064 ...

  3. iOS开发-测量APP启动耗时

    冷启动 冷启动就是App被kill掉以后一切从头开始启动的过程. 热启动 当用户按下home键的时候,iOS的App并不会马上被kill掉,还会继续存活若干时间.理想情况下,用户点击App的图标再次回 ...

  4. 解决ios开发中不合法的网络请求地址

    NSString *const kWebsite = @"http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct ...

  5. IOS开发中如何判断程序第一次启动(根据判断结果决定是否显示新手操作引导)

    IOS开发中如何判断程序第一次启动 在软件下载安装完成后,第一次启动往往需要显示一个新手操作引导,来告诉用户怎么操作这个app,这就需要在程序一开始运行就判断程序是否第一次启动,如果是,则显示新手操作 ...

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

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

  7. iOS开发中常见问题集锦

    在iOS开发中,会出现各种各样的问题.今天,就把这些常见的问题以及各位大牛的解决方案汇总下,方便以后查阅: 常见错误: 1. linker command failed with exit code ...

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

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

  9. 总结iOS开发中的断点续传那些事儿

    前言 断点续传概述 断点续传就是从文件赏赐中断的地方重新开始下载或者上传数据,而不是从头文件开始.当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会从头下载,这样很 ...

随机推荐

  1. UIKIT网页基本结构学习

    没办法,哈哈,以后一段时间,如果公司没有招到合适的运维研发, 啥啥都要我一个人先顶上了~~~:) 也好,可以让人成长. UIKIT,BOOTSTRAP之类的前端,搞一个是有好处的,我们以前即然是用了U ...

  2. 【 HDU 1255】 覆盖的面积(矩阵面积交,线段树,扫描法)

    [题目] 覆盖的面积 Problem Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input 输入数据的第一行是一个正整数T(1<=T<=100 ...

  3. OA学习笔记-008-岗位管理Action层实现

    一.分析 1,设计实体/表 设计实体 --> JavaBean --> hbm.xml --> 建表 2,分析有几个功能,对应几个请求. 3,实现功能: 1,写Action类,写Ac ...

  4. Android实战之你应该使用哪个网络库?

    前言 目前基本上每个应用都会使用HTTP/HTTPS协议来作为主要的传输协议来传输数据.即使你没有直接使用HTTP协议,也会有成堆的SDK会包含这些协议,譬如分析.Crash反馈等等.当然,目前也有很 ...

  5. 通过Microsoft Azure服务设计网络架构的经验分享

    作者 王枫  发布于 2014年4月8日 本文从产品设计和架构角度分享了Microsoft Azure网络服务方面的使用经验,希望你在阅读本文之后能够了解这些服务之间,从而更好地设计你的架构. Mic ...

  6. SIFT算法:DoG尺度空间生产

    SIFT算法:DoG尺度空间生产  SIFT算法:KeyPoint找寻.定位与优化 SIFT算法:确定特征点方向  SIFT算法:特征描述子 目录: 1.高斯尺度空间(GSS - Gauss Scal ...

  7. CodeViz产生函数调用图

    一.安装过程   1.CodeViz的安装 0).确认你已经安装Graphviz[ http://www.graphviz.org/] 1).下载CodeViz.[ http://www.csn.ul ...

  8. JAVA vo pojo javabean dto的区别

    JavaBean 是一种JAVA语言写成的可重用组件.为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器.JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性 ...

  9. Python初始值表示为无穷大

    之前只知道设置变量的初始值为0.今天在写网络路径分析的时候,为了找到离任意坐标距离最近的节点,初始设置最短距离为无穷大,然后不断的去替换,直到找到最近的节点. 刚开始设置是min_dis = 9999 ...

  10. Hadoop之hive安装过程以及运行常见问题

    Hive简介 1.数据仓库工具 2.支持一种与Sql类似的语言HiveQL 3.可以看成是从Sql到MapReduce的映射器 4.提供shall.Jdbc/odbc.Thrift.Web等接口 Hi ...