概述
詳細
目前市場上很多APP(如淘寶、美團、微博、UC)在啟動圖加載完畢后,還會顯示幾秒的廣告,右上角都有個跳過按鈕可以選擇立即跳過這個廣告,有的APP在點擊廣告頁之后還會進入一個廣告頁。
他們玩的樂此不疲,產品汪們見了自然也是不會放過這個效果!
一、主要思路
-
1. 封裝廣告頁, 展現跳過按鈕實現倒計時功能
-
2.判斷廣告頁面是否更新。異步下載新圖片, 刪除老圖片
-
3.廣告頁顯示
-
4.廣告頁點擊后展示頁
二、程序實現
Step1. 封裝廣告頁, 展現跳過按鈕實現倒計時功能
ZLAdvertView.h: 先封裝出來廣告頁,露出顯示廣告頁面方法和圖片路徑
/** * 顯示廣告頁面方法 */ - (void)show; /** * 圖片路徑 */ @property (nonatomic, copy) NSString *filePath;
ZLAdvertView.m:
定義廣告顯示的時間:
static int const showtime = 3;
-
為廣告頁面添加一個點擊手勢,跳轉到廣告頁面.
- (NSTimer *)countTimer { if (!_countTimer) { _countTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(countDown) userInfo:nil repeats:YES]; } return _countTimer; }
- (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { // 1.廣告圖片 _adView = [[UIImageView alloc] initWithFrame:frame]; _adView.userInteractionEnabled = YES; _adView.contentMode = UIViewContentModeScaleAspectFill; _adView.clipsToBounds = YES; // 為廣告頁面添加一個點擊手勢,跳轉到廣告頁面 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pushToAd)]; [_adView addGestureRecognizer:tap]; // 2.跳過按鈕 CGFloat btnW = 60; CGFloat btnH = 30; _countBtn = [[UIButton alloc] initWithFrame:CGRectMake(kscreenWidth - btnW - 24, btnH, btnW, btnH)]; [_countBtn addTarget:self action:@selector(removeAdvertView) forControlEvents:UIControlEventTouchUpInside]; [_countBtn setTitle:[NSString stringWithFormat:@"跳過%d", showtime] forState:UIControlStateNormal]; _countBtn.titleLabel.font = [UIFont systemFontOfSize:15]; [_countBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; _countBtn.backgroundColor = [UIColor colorWithRed:38 /255.0 green:38 /255.0 blue:38 /255.0 alpha:0.6]; _countBtn.layer.cornerRadius = 4; [self addSubview:_adView]; [self addSubview:_countBtn]; } return self; }
- (void)setFilePath:(NSString *)filePath { _filePath = filePath; _adView.image = [UIImage imageWithContentsOfFile:filePath]; }
- (void)pushToAd { [self removeAdvertView]; [[NSNotificationCenter defaultCenter] postNotificationName:@"ZLPushToAdvert" object:nil userInfo:nil]; }
2. 廣告頁面的跳過按鈕倒計時功能可以通過定時器或者GCD實現(這里以廣告倒計時3s 做例子)
- (void)countDown { _count --; [_countBtn setTitle:[NSString stringWithFormat:@"跳過%d",_count] forState:UIControlStateNormal]; if (_count == 0) { [self removeAdvertView]; } }
廣告頁面的跳過按鈕倒計時功能可以通過定時器或者GCD實現:
- (void)show { // 倒計時方法1:GCD // [self startCoundown]; // 倒計時方法2:定時器 [self startTimer]; UIWindow *window = [UIApplication sharedApplication].keyWindow; [window addSubview:self]; }
定時器倒計時:
- (void)startTimer { _count = showtime; [[NSRunLoop mainRunLoop] addTimer:self.countTimer forMode:NSRunLoopCommonModes]; }
GCD倒計時:
- (void)startCoundown { __weak __typeof(self) weakSelf = self; __block int timeout = showtime + 1; //倒計時時間 + 1 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_source_t _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); //每秒執行 dispatch_source_set_event_handler(_timer, ^{ if(timeout <= 0){ //倒計時結束,關閉 dispatch_source_cancel(_timer); dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf removeAdvertView]; }); }else{ dispatch_async(dispatch_get_main_queue(), ^{ [_countBtn setTitle:[NSString stringWithFormat:@"跳過%d",timeout] forState:UIControlStateNormal]; }); timeout--; } }); dispatch_resume(_timer); }
移除廣告頁面:
- (void)removeAdvertView { // 停掉定時器 [self.countTimer invalidate]; self.countTimer = nil; [UIView animateWithDuration:0.3f animations:^{ self.alpha = 0.f; } completion:^(BOOL finished) { [self removeFromSuperview]; }]; }
Step2. 判斷廣告頁面是否更新。異步下載新圖片, 刪除老圖片
因為廣告頁的內容要實時顯示,在無網絡狀態或者網速緩慢的情況下不能延遲加載,或者等到首頁出現了再加載廣告頁。所以這里不采用網絡請求廣告接口去獲取圖片地址然后加載圖片的方式,而是先將圖片異步下載到本地,並保存圖片名,每次打開app時先根據本地存儲的圖片名查找沙盒中是否存在該圖片,如果存在,則顯示廣告頁。
在AppDelegate.m 里設置啟動頁廣告:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[HomeViewController alloc] init]]; [self.window makeKeyAndVisible]; // 設置啟動頁廣告 [self setupAdvert]; return YES; }
-
判斷沙盒中是否存在廣告圖片,如果存在,直接顯示
/** * 設置啟動頁廣告 */ - (void)setupAdvert { // 1.判斷沙盒中是否存在廣告圖片,如果存在,直接顯示 NSString *filePath = [self getFilePathWithImageName:[kUserDefaults valueForKey:adImageName]]; BOOL isExist = [self isFileExistWithFilePath:filePath]; if (isExist) { // 圖片存在 ZLAdvertView *advertView = [[ZLAdvertView alloc] initWithFrame:self.window.bounds]; advertView.filePath = filePath; [advertView show]; } // 2.無論沙盒中是否存在廣告圖片,都需要重新調用廣告接口,判斷廣告是否更新 [self getAdvertisingImage]; } /** * 判斷文件是否存在 */ - (BOOL)isFileExistWithFilePath:(NSString *)filePath { NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDirectory = FALSE; return [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory]; }
2.無論沙盒中是否存在廣告圖片,都需要重新調用獲取廣告接口,判斷廣告是否更新
/** * 初始化廣告頁面 */ - (void)getAdvertisingImage { // TODO 請求廣告接口 // 這里原本應該采用廣告接口,現在用一些固定的網絡圖片url代替 NSArray *imageArray = @[ @"https://ss2.baidu.com/-vo3dSag_xI4khGko9WTAnF6hhy/super/whfpf%3D425%2C260%2C50/sign=a4b3d7085dee3d6d2293d48b252b5910/0e2442a7d933c89524cd5cd4d51373f0830200ea.jpg", @"https://ss0.baidu.com/-Po3dSag_xI4khGko9WTAnF6hhy/super/whfpf%3D425%2C260%2C50/sign=a41eb338dd33c895a62bcb3bb72e47c2/5fdf8db1cb134954a2192ccb524e9258d1094a1e.jpg", @"http://c.hiphotos.baidu.com/image/w%3D400/sign=c2318ff84334970a4773112fa5c8d1c0/b7fd5266d0160924c1fae5ccd60735fae7cd340d.jpg" ]; NSString *imageUrl = imageArray[arc4random() % imageArray.count]; // 獲取圖片名:43-130P5122Z60-50.jpg NSArray *stringArr = [imageUrl componentsSeparatedByString:@"/"]; NSString *imageName = stringArr.lastObject; // 拼接沙盒路徑 NSString *filePath = [self getFilePathWithImageName:imageName]; BOOL isExist = [self isFileExistWithFilePath:filePath]; if (!isExist){ // 如果該圖片不存在,則刪除老圖片,下載新圖片 [self downloadAdImageWithUrl:imageUrl imageName:imageName]; } }
3.異步下載新圖片, 刪除老圖片
/** * 下載新圖片 */ - (void)downloadAdImageWithUrl:(NSString *)imageUrl imageName:(NSString *)imageName { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]]; UIImage *image = [UIImage imageWithData:data]; NSString *filePath = [self getFilePathWithImageName:imageName]; // 保存文件的名稱 if ([UIImagePNGRepresentation(image) writeToFile:filePath atomically:YES]) {// 保存成功 NSLog(@"保存成功"); [self deleteOldImage]; [kUserDefaults setValue:imageName forKey:adImageName]; [kUserDefaults synchronize]; // 如果有廣告鏈接,將廣告鏈接也保存下來 }else{ NSLog(@"保存失敗"); } }); } /** * 刪除舊圖片 */ - (void)deleteOldImage { NSString *imageName = [kUserDefaults valueForKey:adImageName]; if (imageName) { NSString *filePath = [self getFilePathWithImageName:imageName]; NSFileManager *fileManager = [NSFileManager defaultManager]; [fileManager removeItemAtPath:filePath error:nil]; } } /** * 根據圖片名拼接文件路徑 */ - (NSString *)getFilePathWithImageName:(NSString *)imageName { if (imageName) { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES); NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:imageName]; return filePath; } return nil; }
Step3. 廣告頁顯示
廣告頁的顯示代碼可以放在AppDeleate中,也可以放在首頁的控制器中。如果代碼是在AppDelegate中,可以通過發送通知的方式,讓首頁push到廣告詳情頁.
首頁控制器HomeViewController.m:
#import "HomeViewController.h" #import "ZLAdvertViewController.h" @interface HomeViewController () @end @implementation HomeViewController - (void)viewDidLoad { [super viewDidLoad]; self.title = @"首頁"; self.view.backgroundColor = [UIColor greenColor]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pushToAd) name:@"ZLPushToAdvert" object:nil]; } // 進入廣告鏈接頁 - (void)pushToAd { ZLAdvertViewController *adVc = [[ZLAdvertViewController alloc] init]; [self.navigationController pushViewController:adVc animated:YES]; } @end
Step4. 廣告頁點擊后展示頁。
如果點擊廣告需要跳轉廣告詳情頁面,那么廣告鏈接地址也需要用NSUserDefaults存儲。注意:廣告詳情頁面是從首頁push進去的
廣告鏈接頁ZLAdvertViewController, 露出廣告url :
@property (nonatomic, copy) NSString *adUrl;
ZLAdvertViewController.m 測試連接 :
- (void)setAdUrl:(NSString *)adUrl { _adUrl = adUrl; }
三、壓縮文件截圖及運行效果
1、壓縮文件截圖
2、 運行時的效果
啟動頁進入廣告效果:
啟動頁跳過廣告效果:
四、其他補充
注意:
廣告頁面的底部和啟動圖的底部一般都是相同的,給用戶的錯覺就是啟動圖加載完之后把廣告圖放在了啟動圖上,而且不能有偏差。所以我們開發要圖時需要提醒美工在制作廣告圖的時候要注意下。
界面性問題可以根據自己項目需求調整即可, 具體可參考代碼, 項目能夠直接運行!
注:本文著作權歸作者,由demo大師發表,拒絕轉載,轉載需要作者授權