iOS實現(xiàn)逐幀動畫做loading視圖
更新時間:2021年05月18日 14:24:45 作者:shannonchou
這篇文章主要為大家詳細(xì)介紹了iOS實現(xiàn)逐幀動畫做loading視圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了iOS實現(xiàn)逐幀動畫做loading視圖的具體代碼,供大家參考,具體內(nèi)容如下
我封裝了一個可復(fù)用的loading視圖組件,用于按照一定周期逐幀播放加載動畫。代碼如下:
.h文件
#import <UIKit/UIKit.h>
//加載狀態(tài)
typedef enum {
FZImageSequenceLoadingStatusStop = 1, // 停止
FZImageSequenceLoadingStatusLoading, // 加載中
FZImageSequenceLoadingStatusError //發(fā)生錯誤
} FZImageSequenceLoadingStatus;
@interface FZImageSequenceLoadingView : UIView {
UIImageView *_imageView;
UILabel *_lblMsg;
NSTimer *timer;
int currentImageIndex;
}
@property(strong) NSArray *imageArray; //動畫序列的圖片數(shù)組
@property(strong, nonatomic) UIImage *errorImage;
@property(nonatomic, strong) NSString *errorMsg;
@property(nonatomic, strong) NSString *loadingMsg; //提示文字
@property(nonatomic) CGRect imageFrame; //圖片的Frame
@property(nonatomic) CGRect msgFrame; //文字內(nèi)容的Frame
@property(nonatomic) float timerInterval; //切換圖片的周期
/**
切換狀態(tài)
*/
- (void)switchToStatus:(FZImageSequenceLoadingStatus)status;
/**
通過圖片名字和數(shù)量設(shè)置圖片數(shù)組,如給定名字"name"、“.png”和數(shù)量4,則會去加載“name_1.png”到"name_4.png"的圖片
*/
- (void)setImageArrayByName:(NSString *)name andExtName:(NSString *)extName andCount:(int)count;
@end
.m文件
#import "FZImageSequenceLoadingView.h"
@implementation FZImageSequenceLoadingView
@synthesize errorImage;
@synthesize errorMsg;
@synthesize imageArray;
@synthesize loadingMsg;
@synthesize timerInterval;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
timerInterval = 1;
currentImageIndex = -1;
}
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
- (void)setupSubviews {
// self.backgroundColor = [UIColor redColor];
if (self.imageArray && self.imageArray.count > 0) {
if (!_imageView) {
_imageView = [[UIImageView alloc] init];
[self addSubview:_imageView];
}
//讓圖片view為本view的頂部居中,大小為圖片數(shù)組中的第一張
UIImage *firstImg = [self.imageArray objectAtIndex:0];
_imageView.size = firstImg.size;
_imageView.top = 0;
_imageView.left = (self.size.width - _imageView.size.width) / 2;
}
if (self.loadingMsg) {
CGSize labelSize = [self.loadingMsg sizeWithFont:[UIFont systemFontOfSize:11]];
if (!_lblMsg) {
_lblMsg = [[UILabel alloc] initWithFrame:CGRectZero];
_lblMsg.textAlignment = NSTextAlignmentCenter;
[self addSubview:_lblMsg];
}
_lblMsg.font = [UIFont systemFontOfSize:11];
_lblMsg.size = labelSize;
_lblMsg.textColor = [UIColor darkGrayColor];
_lblMsg.backgroundColor = [UIColor clearColor];
_lblMsg.bottom = self.height;
_lblMsg.left = (self.width - _lblMsg.width) / 2;
}
}
- (void)switchToStatus:(FZImageSequenceLoadingStatus)status {
if (!_lblMsg || !_imageView) {
[self setupSubviews];
}
switch (status) {
case FZImageSequenceLoadingStatusError:
[self switchToError];
break;
case FZImageSequenceLoadingStatusLoading:
[self switchToLoading];
break;
case FZImageSequenceLoadingStatusStop:
[self switchToStop];
break;
}
}
- (void)switchToStop {
[timer invalidate];
timer = nil;
if (self.imageArray && self.imageArray.count > 0) {
_imageView.image = [self.imageArray objectAtIndex:0];
}
}
- (void)switchToError {
[timer invalidate];
timer = nil;
//如果有錯誤狀態(tài)的圖
if (self.errorImage) {
_imageView.image = self.errorImage;
//如果沒有就用第一張動畫圖
} else if (self.imageArray && self.imageArray.count > 0) {
_imageView.image = [self.imageArray objectAtIndex:0];
}
if (self.errorMsg) {
_lblMsg.text = self.errorMsg;
}
}
- (void)switchToLoading {
if (self.loadingMsg) {
_lblMsg.text = self.loadingMsg;
}
if (!timer) {
timer = [NSTimer scheduledTimerWithTimeInterval:self.timerInterval target:self selector:@selector(showNextImage) userInfo:nil repeats:YES];
}
}
- (void)showNextImage {
if (!imageArray || imageArray.count < 1) {
return;
}
currentImageIndex = (currentImageIndex + 1) % self.imageArray.count;
// 主線程執(zhí)行:
dispatch_async(dispatch_get_main_queue(), ^{
_imageView.image = [imageArray objectAtIndex:currentImageIndex];
});
}
- (void)setImageArrayByName:(NSString *)name andExtName:(NSString *)extName andCount:(int)count {
NSAssert((name && extName && (count > 0)), @"圖片名字和數(shù)量錯誤");
NSMutableArray *imgs = [NSMutableArray arrayWithCapacity:count];
for (int i = 1; i <= count; i++) {
NSString *imgName = [NSString stringWithFormat:@"%@_%i%@", name, i, extName];
UIImage *image = [UIImage imageNamed:imgName];
NSLog(@"%@", image);
if (!image) {
continue;
}
[imgs addObject:image];
}
self.imageArray = imgs;
}
@end
使用示例,在uiwebview中使用如下:
初始化視圖:
//設(shè)置loading視圖
- (void)setupLoadingView {
if (!_loadingView) {
_loadingView = [[FZImageSequenceLoadingView alloc] initWithFrame:CGRectMake(0, 0, 170, 70)];
_loadingView.center = self.view.center;
[_loadingView setImageArrayByName:@"loading" andExtName:@".png" andCount:10];
_loadingView.loadingMsg = @"努力加載中,請稍候";
_loadingView.errorMsg = @"加載失敗";
_loadingView.timerInterval = 0.1;
_loadingView.hidden = YES;
[self.view addSubview:_loadingView];
}
}
在uiwebview的代理方法中切換狀態(tài):
#pragma mark - webview delegate
- (void)webViewDidStartLoad:(UIWebView *)webView {
if (_loadingView.hidden) {
_loadingView.hidden = NO;
[_loadingView switchToStatus:FZImageSequenceLoadingStatusLoading];
}
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if (!_loadingView.hidden) {
[_loadingView switchToStatus:FZImageSequenceLoadingStatusStop];
_loadingView.hidden = YES;
}
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
NSLog(@"load page error:%@", [error description]);
if (!_loadingView.hidden) {
[_loadingView switchToStatus:FZImageSequenceLoadingStatusError];
}
}
目前該組件功能還不夠完善,但是能滿足目前我自己的需求,后續(xù)再繼續(xù)豐富。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
iOS App開發(fā)中通過UIDevice類獲取設(shè)備信息的方法
UIDevice最常見的用法就是用來監(jiān)測iOS設(shè)備的電量了,然后再實現(xiàn)電池狀態(tài)通知非常方便,除此之外還有傳感器等信息的獲取,這里我們就來總結(jié)一下iOS App開發(fā)中通過UIDevice類獲取設(shè)備信息的方法:2016-07-07
替代pod update速度慢的lg_pod_plugin安裝使用詳解
這篇文章主要介紹了替代pod update速度慢lg_pod_plugin安裝使用方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09

