现在越来越多的的app都在打开的时候显示一些从网上加载的广告或者活动,可能很多人和我开始的想法一样,认为在这些广告显示的时候,APP会在后台初始化视图控制器操作,实际上并不是这个样子的。 先说说一般的实现方式,如果在网上搜索一下,大家会看到很多的实现方式,意思都差不多,就是在 - (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions方法中,把一个view(广告视图) 放到keyWindow上或者放到 rootViewController 的view上。
很自然,我们想到,先加载广告、显示(假设加载和显示一共耗时3s),然后在后台初始化rootViewController(假设需要1s),那么我们就节约了1s的时间(初始化视图控制器的时间)。
实际上并不是想象中的那个样子,在- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions 方法结束之前,launchScreen是不会消失的,而创建keyWindow的rootViewController会使用主线程创建,也就是说,只有当rootViewController创建完成且 该方法执行完成之后,欢迎界面才会消失,如果采用先加载广告,再初始化rootViewController那么实际上添加到 keyWindow上的广告是被遮住了的。
所以只有在rootViewController加载完成之后使用同步方式加载广告界面,并显示到rootViewController的view上是比较合适的。
自己动手封装一个简单使用的广告加载类:
效果图:
主思路:主视图控制器加载完成之后将一个广告view 放在 主视图控制器的view上。
分析:一般广告是,一张大图片,一个跳过按钮,点击广告触发特定事件。
所以这个view可以继承imageView,并在之前声明一个协议
下面直接贴代码:
创建一个类,继承UIImageView,取名叫做CQAdView
.h文件中
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
@protocol CQAdViewDelegate <NSObject>
- (void)didtapTheAdViewWithObject:(id)object;
@end
@interface CQAdView : UIImageView
@property (nonatomic, copy) NSString *imageURLString;
///持续时间,默认3s
@property NSTimeInterval duration;
@property (nonatomic, weak) id<CQAdViewDelegate> delegate;
- (void)showInViewController:(UIViewController *)viewController;
@end
为了方便使用,我们需要通过runtime和类别给UIViewController增加广告视图这个属性(我写在了 CQAdView这个类的声明文件中,也可以写到其他文件中)
@interface UIViewController(CQAdView)
@property (nonatomic, strong) CQAdView *cq_AdView;
@end
static void *adViewKey = &adViewKey;
@implementation UIViewController(CQAdView)
- (void)setCq_AdView:(CQAdView *)cq_AdView {
objc_setAssociatedObject(self, &adViewKey, cq_AdView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (CQAdView *)cq_AdView {
return objc_getAssociatedObject(self, &adViewKey);
}
@end
.m文件中的代码如下
#import "CQAdView.h"
@implementation CQAdView
@synthesize imageURLString = _imageURLString;
- (instancetype)init {
if (self = [super init]) {
[self initDatas];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self initDatas];
}
return self;
}
- (void)initDatas {
self.userInteractionEnabled = YES;
self.duration = 3.0;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
[self addGestureRecognizer:tap];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = self.frame;
CGFloat w = 40;
CGFloat gap = 15;
button.frame = CGRectMake(frame.size.width - w - gap, gap, w, w);
button.backgroundColor = [UIColor grayColor];
button.layer.masksToBounds = YES;
button.layer.cornerRadius = w/2;
[button setTitle:@"跳过" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonSkipAction:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button];
}
- (IBAction)buttonSkipAction:(id)sender {
[self removeFromSuperview];
}
- (IBAction)tapAction:(id)sender {
if ([_delegate respondsToSelector:@selector(didtapTheAdViewWithObject:)]) {
[_delegate didtapTheAdViewWithObject:nil];
}
}
- (void)showInViewController:(UIViewController *)viewController {
[viewController.view addSubview:viewController.cq_AdView];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (self.superview) {
[self removeFromSuperview];
}
});
}
- (void)setImageURLString:(NSString *)imageURLString {
_imageURLString = imageURLString;
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:_imageURLString]] scale:1.0];
self.image = image;
}
- (NSString *)imageURLString {
return _imageURLString;
}
在appDelegate中的使用方法如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
rootVC *viewController = [[rootVC alloc] init];
viewController.view.backgroundColor = [UIColor orangeColor];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
viewController.cq_AdView = [[CQAdView alloc] initWithFrame:CGRectMake(0, 0, 375, 667)];
viewController.cq_AdView.duration = 5;
viewController.cq_AdView.imageURLString = @"http://e.hiphotos.baidu.com/zhidao/pic/item/63d0f703918fa0ecc4380cbd209759ee3c6ddb87.jpg";
[viewController.cq_AdView showInViewController:viewController];
return YES;
}