相信大家都看过很多app在启动时候会加载一些广告图片,例如微博、淘宝、头条等。下边我们就来实现类似的效果。
首先,我们要先拿到项目设置启动页的图片,我们可以给UIImage写个Category代码如下:
.h文件
#import <UIKit/UIKit.h>
@interface UIImage (XLLaunchImage)
//有两种加载启动页的设置方式 如果使用LaunchScreen.storyboard来设置启动页bIsLaunchImage 设置成NO 如果是使用LaunchImage来设置 bIsLaunchImage 设置成YES
+ (UIImage *)getLaunchImageWithbIsLaunchImage:(BOOL)bIsLaunchImage;
@end
.m文件
+ (UIImage *)getLaunchImageWithbIsLaunchImage:(BOOL)bIsLaunchImage
{
if (!bIsLaunchImage) {
// 通过LaunchScreen.StoryBoard加载的本地图片 只需要两张本地图片iPhone 7和 7 plus尺寸的图 取名为LaunchImage@2x.png 和LaunchImage@3x.png
UIViewController *viewController = [[UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil] instantiateViewControllerWithIdentifier:@"LaunchScreen"];
UIImageView * imageView=viewController.view.subviews[0];
return imageView.image;
}else{
//下面是通过LaunchImage 获取的本地图片 需要四张本地图片 放入LaunchImage即可 不包括横屏和竖屏
NSString *viewOrientation = @"Portrait";
// if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
// viewOrientation = @"Landscape";
// }
NSString *launchImageName = nil;
NSArray* imagesDict = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"UILaunchImages"];
CGSize viewSize = [UIApplication sharedApplication].keyWindow.bounds.size;
for (NSDictionary* dict in imagesDict)
{
CGSize imageSize = CGSizeFromString(dict[@"UILaunchImageSize"]);
if (CGSizeEqualToSize(imageSize, viewSize) && [viewOrientation isEqualToString:dict[@"UILaunchImageOrientation"]])
{
launchImageName = dict[@"UILaunchImageName"];
}
}
return [UIImage imageNamed:launchImageName];
}
}
这边要说明一下,设置启动页有两种方式一种是通过LaunchScreen.storyboard来设置,一种是通过LaunchImage(也就是Launch images source)来设置这两个我们获取的方式是不一样的。
接着我们要来创建一个View类,用于展示我们自定义的广告图片。代码如下:
.h文件
#import <UIKit/UIKit.h>
#import "FLAnimatedImage.h"
//屏幕高度
#define kScreenHeight CGRectGetHeight([UIScreen mainScreen].bounds)
//屏幕宽度
#define kScreenWidth CGRectGetWidth([UIScreen mainScreen].bounds)
//跳过按钮宽
#define kSkipBtnWidth 65
//跳过按钮高
#define kSkipBtnHeight 30
//跳过按钮右边距
#define kSkipRightEdging 20
//跳过按钮顶部边距
#define kSkipTopEdging 40
//默认广告页面高度
#define kAdImageViewHeight kScreenHeight-100
@interface XLLaunchView : UIView
@property (nonatomic, weak) UIImageView *launchImageView;
@property (nonatomic, weak) FLAnimatedImageView *adImageView;
@property (nonatomic, weak) UIButton *skipBtn;
@end
.m文件
#import "XLLaunchView.h"
@interface XLLaunchView ()
@end
@implementation XLLaunchView
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self addlaunchImageView];
[self addAdImageView];
[self addSkipBtn];
}
return self;
}
- (void)addlaunchImageView
{
UIImageView *imageView = [[UIImageView alloc]init];
[self addSubview:imageView];
_launchImageView = imageView;
}
- (void)addAdImageView
{
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc]init];
[self addSubview:imageView];
_adImageView = imageView;
}
//跳过按钮
- (void)addSkipBtn
{
UIButton *skipBtn = [UIButton buttonWithType:UIButtonTypeCustom];
skipBtn.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.3];
[skipBtn setTitle:@"跳过" forState:UIControlStateNormal];
skipBtn.titleLabel.textColor = [UIColor whiteColor];
skipBtn.titleLabel.font = [UIFont systemFontOfSize:15];
skipBtn.alpha = 0.92;
skipBtn.layer.cornerRadius = 4.0;
skipBtn.clipsToBounds = YES;
[self addSubview:skipBtn];
_skipBtn = skipBtn;
}
- (void)layoutSubviews
{
[super layoutSubviews];
_launchImageView.frame = self.bounds;
_adImageView.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight-100);
_skipBtn.frame = CGRectMake(CGRectGetWidth(self.frame) - kSkipBtnWidth - kSkipRightEdging, kSkipTopEdging, kSkipBtnWidth, kSkipBtnHeight);
}
@end
这边也要说明一下,我们这边图片是通过SDWebImage来进行加载的,而FLAnimatedImage.h这个类是SDWebImage4.0版本以上加载动态图的类,性能比之前的提升了很多,具体的使用这里不多说请点SDWebImage使用
最后,我们可以创建一个LaunchImageVIew的管理者,方便我们来进行一些对应的操作。代码如下:
.h文件
#import <UIKit/UIKit.h>
//广告倒计时间 单位:秒
#define DURATION 5
@class XLAdModel;
@interface XLLaunchViewManager : UIView
//广告模型
@property (nonatomic , strong) XLAdModel *adModel;
//点击广告图回调
@property (nonatomic , copy) void(^tapClick) ();
//创建一个对象
+(instancetype)launchViewManger;
//展示对象
-(void)showView:(UIView *)view;
@end
.m文件
#import "XLLaunchViewManager.h"
#import "XLLaunchView.h"
#import "UIImageView+WebCache.h"
#import "UIImage+XLLaunchImage.h"
#import "XLAdModel.h"
#import "FLAnimatedImageView+WebCache.h"
@interface XLLaunchViewManager ()
@property (nonatomic, weak) XLLaunchView *launchView;
@property (nonatomic, strong) dispatch_source_t timer;
@end
@implementation XLLaunchViewManager
+(instancetype)launchViewManger
{
return [[[ self class]alloc]init];
}
-(void)showView:(UIView *)view
{
self.frame = view.bounds;
[view addSubview:self];
[self addADLaunchView];
[self loadData];
}
- (void)addADLaunchView
{
XLLaunchView *adLaunchView = [[XLLaunchView alloc]init];
adLaunchView.skipBtn.hidden = YES;
//有两种加载启动页的设置方式 如果使用LaunchScreen.storyboard来设置启动页bIsLaunchImage 设置成NO 如果是使用LaunchImage来设置 bIsLaunchImage 设置成YES
adLaunchView.launchImageView.image = [UIImage getLaunchImageWithbIsLaunchImage:YES];
adLaunchView.frame = self.bounds;
[adLaunchView.skipBtn addTarget:self action:@selector(skipADAction) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:adLaunchView];
_launchView = adLaunchView;
}
//加载数据
- (void)loadData
{
if ( _adModel.launchUrl && _adModel.launchUrl.length>0) {
[self showADImageWithURL:[NSURL URLWithString:_adModel.launchUrl]];
UITapGestureRecognizer * tap=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(pushAdController)];
[_launchView addGestureRecognizer:tap];
}else{
[self dismissController];
}
}
//设置广告图片
- (void)showADImageWithURL:(NSURL *)url
{
__weak typeof(self) weakSelf = self;
[_launchView.adImageView sd_setImageWithURL:url placeholderImage:nil options:SDWebImageRetryFailed completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
// 启动倒计时
[weakSelf scheduledGCDTimer];
}];
}
//跳过倒计时
- (void)showSkipBtnTitleTime:(int)timeLeave
{
NSString *timeLeaveStr = [NSString stringWithFormat:@"跳过 %ds",timeLeave];
[_launchView.skipBtn setTitle:timeLeaveStr forState:UIControlStateNormal];
_launchView.skipBtn.hidden = NO;
}
- (void)scheduledGCDTimer
{
[self cancleGCDTimer];
__block int timeLeave = DURATION; //倒计时时间
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒执行
__typeof (self) __weak weakSelf = self;
dispatch_source_set_event_handler(_timer, ^{
if(timeLeave <= 0){ //倒计时结束,关闭
dispatch_source_cancel(weakSelf.timer);
dispatch_async(dispatch_get_main_queue(), ^{
//关闭界面
[self dismissController];
});
}else{
int curTimeLeave = timeLeave;
dispatch_async(dispatch_get_main_queue(), ^{
//设置界面
[weakSelf showSkipBtnTitleTime:curTimeLeave];
});
--timeLeave;
}
});
dispatch_resume(_timer);
}
- (void)cancleGCDTimer
{
if (_timer) {
dispatch_source_cancel(_timer);
_timer = nil;
}
}
#pragma mark - action
- (void)skipADAction
{
[self dismissController];
}
- (void)dismissController
{
[self cancleGCDTimer];
//消失动画
[UIView animateWithDuration:0.0 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
//缩放修改处
self.transform = CGAffineTransformMakeScale(1, 1);
self.alpha = 0.0;
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
-(void)pushAdController
{
dispatch_async(dispatch_get_main_queue(), ^{
[self removeFromSuperview];
if (self.tapClick) {
self.tapClick();
}
});
}
- (void)dealloc
{
[self cancleGCDTimer];
}
-(void)show
{
[self addADLaunchView];
[self loadData];
}
@end
这边有个XLAdModel类,这个是广告Model参数如下
@interface XLAdModel : NSObject
//启动图广告地址
@property (nonatomic , copy) NSString *launchUrl;
//启动图广告详情地址
@property (nonatomic , copy) NSString *adDetailUrl;
@end
到这边我们是准备都完成,接下来就是怎么来使用了,使用代码如下:
AppDelegate.m文件
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self addMainWindow];
[self addADLaunchController];
return YES;
}
- (void)addMainWindow
{
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];
_nav = [[UINavigationController alloc] initWithRootViewController:[[MainViewController alloc] init]];
self.window.rootViewController = _nav;
[self.window makeKeyAndVisible];
}
//加载广告
- (void)addADLaunchController
{
XLAdModel * adModel=[[XLAdModel alloc]init];
//静态图
// adModel.launchUrl = @"http://d.hiphotos.baidu.com/image/pic/item/f7246b600c3387444834846f580fd9f9d72aa034.jpg";
//动态图
adModel.launchUrl = @"https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=408862874,416826962&fm=23&gp=0.jpg";
// //点击跳转链接
adModel.adDetailUrl = @"http://www.baidu.com";
UIViewController *rootViewController = self.window.rootViewController;
XLLaunchViewManager *launchController = [XLLaunchViewManager launchViewManger];
launchController.adModel = adModel;
[launchController showView:rootViewController.view];
__weak typeof(self)weakSelf = self;
launchController.tapClick =^{
XLAdViewController * adVc=[[XLAdViewController alloc]init];
adVc.adModel = adModel;
adVc.hidesBottomBarWhenPushed=YES;
[weakSelf.nav pushViewController:adVc animated:YES];
};
}
这边的XLAdViewController是广告的具体详情页面,具体可自己实现。到这边就基本可以完成了,效果如下: