目前大多数APP的启动图片还是launchImage的形式,这张启动图片显示的时间很短,大概不到0.5s左右,有时候我们启动的时候一些初始化的步骤或者网络不好的情况会花掉1~2s的时间,会造成很不好的体验,网上有人说让线程睡1s,但是这个睡眠过程中app不会做任何事,只是单纯的延长了启动图片的时间。还有就是一些节假日app想要发布一些主题开屏,但是公司的输求是不能在app中预留这些图片,只能从网络中获取。
于是乎我有了余下的想法:
1>启动时,下载一张图片到launchImage中,然后用于下一次启动。这样的好处就是能做到无缝衔接,不会有过渡的过程。(这种方法不知道能不能实现)
2>launchImage放一张只带有logo的白色图片,然后再app中放一张基本上能通用的图片,主题开屏的图片从网上下载。在app中放一张通用的开屏图片是为了防止主题图片没有下载好用到的。从只有白色logo的启动图片到开屏图的过渡时间在iphone7大概只有0.2s左右,5s大概是0.5s左右。放白色logo图也就是为了过渡自然的效果,废话不多说上代码。
2.1>先初始化window,加载主控制器,在window上放的这张图片的时间是3s,网络基本还行的情况下,3s首页的一些初始化、请求是基本能做完的。
self.window=[[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor whiteColor];
self.window.rootViewController = [[ALSRootViewController alloc] init];
[self.window makeKeyAndVisible];
ALSLaunchImageView *launchImageView = [[ALSLaunchImageView alloc] init];
[self.window addSubview:launchImageView];
[ALSLaunchImageView loadNewLaunchImage];
2.2> 初始化,用到的图片是上一次启动下载的,这也是为了使过渡时间尽可能的减小,第一次启动用的是通用的那张开屏的图片
- (instancetype)init
{
if (self = [super init]) {
CGSize viewSize = CGSizeMake(KScreenWidth, KScreenHeight);
//横屏请设置成 @"Landscape"
NSString *viewOrientation = @"Portrait";
NSString *launchImageName;
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 * bgImage = [UIImage imageNamed:launchImageName];
//将app里面的launchImage这张图片渲染到自身背景色
self.backgroundColor = [UIColor colorWithPatternImage:bgImage];
self.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight);
NSString *saveDiretory = [NSString stringWithFormat:@"%@/image",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) lastObject]];
NSString *launchImagePath =[NSString stringWithFormat: @"%@/launchImage.png",saveDiretory];
NSData *launchImageData = [NSData dataWithContentsOfFile:launchImagePath];
UIImage *launchImage;
if (launchImageData) {//如果本地文件夹有下载的网络图片就用网络的
launchImage = [UIImage imageWithData:launchImageData];
} else {//没有就用放在APP里面的图片
launchImage = [UIImage imageNamed:@"default_launchImage"];
}
//设置成图片
UIImageView *launchImageView = [[UIImageView alloc] init];
//0 全屏 1 带logo的屏
BOOL launchImageType = [ALSUserDefaults boolForKey:@"launchImageType"];
if (launchImageType) {
launchImageView.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight - KScreenWidth / 3);
} else {
launchImageView.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight);
}
//设置图片,带logo的需要剪裁
launchImageView.image = [self clipImage:launchImage targetSize:launchImageView.size];
[self addSubview:launchImageView];
//需要打开接收事件,不然会有穿透效果
self.userInteractionEnabled = YES;
//怕商品推送图片过来时,启动图片在推送图片的下面
self.layer.zPosition = 10;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self closeAddImgAnimation];
});
}
return self;
}
2.3>剪裁图片
- (UIImage *)clipImage:(UIImage *)sourceImage targetSize:(CGSize)defineSize {
if(defineSize.height == KScreenHeight){
return sourceImage;
} else { //半屏 需要剪裁
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat targetWidth = defineSize.width;
CGFloat widthSacler = width / targetWidth;
CGFloat height = widthSacler * defineSize.height;
CGSize size = CGSizeMake(width, height);
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, size.width, size.height)];
[path addClip];
// 5.画图片
[sourceImage drawAtPoint:CGPointZero];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
}
2.4>下载图片,是否全屏显示由后台决定的
+ (void)loadNewLaunchImage {
NSString *url = [baseStr stringByAppendingString:@"api/app/appScreensaverAction_search"];
[ALSHttpTool GetWithURL:url params:nil success:^(id json) {
ALSLog(@"%@",json);
if ([json[@"rs"] integerValue] == 200) {
NSInteger type = [json[@"content"][@"type"] integerValue];
[ALSUserDefaults setBool:type forKey:@"launchImageType"];
[[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:json[@"content"][@"image"]] options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (image) {
NSFileManager *fm = [NSFileManager defaultManager];
NSString *saveDiretory = [NSString stringWithFormat:@"%@/image",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) lastObject]];
BOOL isDirectory ;
BOOL isExist = [fm fileExistsAtPath:saveDiretory isDirectory:&isDirectory];
if (!isExist) {
[fm createDirectoryAtPath:saveDiretory withIntermediateDirectories:NO attributes:nil error:nil];
}
//写入图片
NSString *savePath =[NSString stringWithFormat: @"%@/launchImage.png",saveDiretory];
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:savePath atomically:YES];
}
}];
}
} failure:^(NSError *error) {
}];
}
2.5>移除launchImage
-(void)closeAddImgAnimation
{
//这个比较自然,设置alpha比较舒服
[UIView animateWithDuration:0.3 animations:^{
self.alpha = 0;
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
开屏广告也是差不多的,后台获取的图片不能用于下一次,可能会有点延时。然后加一个跳过按钮,让图片接受事件,大同小异,最主要的就是将放在app里面imageLaunch这张图片渲染成背景色,以及图片剪裁的处理
网友评论