SVProgressHUD簡單使用以及自定義動畫

SVProgressHUD 是一個干凈,易于使用的HUD,旨在顯示iOS和tvOS正在進行的任務的進展。
常用的還有MBProgressHUD.這兩個都是很常用的HUD,大體相似,但是還是有一些不同的.
MBProgressHUD和SVProgressHUD的區別:
svprogresshud 使用起來很方便,但 可定制 差一些,看它的接口貌似只能添加一個全屏的HUD,不能把它添加到某個視圖上面去.
MBProgressHUD 功能全一些,可定制 高一些,而且可以指定加到某一個View上去.用起來可能就沒上面那個方便了.
具體還要看你的使用場景.
附上GitHub源碼地址:
SVProgressHUD:https://github.com/SVProgressHUD/SVProgressHUD
MBProgressHUD:https://github.com/jdg/MBProgressHUD
今天我們不對二者的區別做詳解,有空我會專門寫文章對它們的區別做一個詳解.
今天我們主要簡單介紹一下SVProgressHUD的使用.

安裝

通過CocoaPods安裝,在Podfile中加入pod 'SVProgressHUD',這里不多做介紹.可以參考文章: CocoaPods的簡單使用

使用

SVProgressHUD是已經被創建為單例的,所以不需要被實例化了,可以直接使用.調用它的方法[SVProgressHUD method].

[SVProgressHUD show ];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^ {
     //耗時的任務
    dispatch_async(dispatch_get_main_queue(),^ {
        [SVProgressHUD dismiss ];
    });
});

顯示HUD

可以在下拉刷新或者執行其他耗時任務的時候,使用下面方法之一,來顯示不確定任務的狀態:

+ (void)show;
+ (void)showWithStatus:(NSString*)string;

效果圖分別為:


show(不帶文字)
showWithStatus(帶文字)

如果你希望HUD反應任務的進度,可以使用下面方法的其中一個:

+ (void)showProgress:(CGFloat)progress;
+ (void)showProgress:(CGFloat)progress status:(NSString*)status;

通過其他方式可以實現進度條的速度把控.比如:

- (IBAction)clickButtonsShowWithProgress:(id)sender {
    progress = 0.0f;
    [SVProgressHUD showProgress:0 status:@"Loading"];
    [self performSelector:@selector(increaseProgress) withObject:nil afterDelay:0.1f];
}

- (void)increaseProgress {
    progress += 0.05f;
    [SVProgressHUD showProgress:progress status:@"xuanhe Loading"];

    if(progress < 1.0f){
        [self performSelector:@selector(increaseProgress) withObject:nil afterDelay:0.1f];
    } else {
        [self performSelector:@selector(dismiss) withObject:nil afterDelay:0.4f];
    }
}

效果如下


進度

還有其他常用的語法:

+(void)showInfoWithStatus :( NSString *)string;
+(void)showSuccessWithStatus :( NSString *)string;
+(void)showErrorWithStatus :( NSString *)string;
+(void)showImage:(UIImage *)image status :( NSString *)string;

取消HUD

HUD可以使用以下方式解除:

+(void)dismiss;
+(void)dismissWithDelay :( NSTimeInterval)delay;
+ (void)dismissWithDelay:(NSTimeInterval)delay completion:(SVProgressHUDDismissCompletion)completion;

可以對這些代碼進行改進,比如,在彈框結束后執行其他操作.可以封裝一個方法,彈框結束后,執行Block.

定制

SVProgressHUD 可以通過以下方法定制:

+ (void)setDefaultStyle:(SVProgressHUDStyle)style;                  // default is SVProgressHUDStyleLight
+ (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType;         // default is SVProgressHUDMaskTypeNone
+ (void)setDefaultAnimationType:(SVProgressHUDAnimationType)type;   // default is SVProgressHUDAnimationTypeFlat
+ (void)setContainerView:(UIView*)containerView;                    // default is window level
+ (void)setMinimumSize:(CGSize)minimumSize;                         // default is CGSizeZero, can be used to avoid resizing
+ (void)setRingThickness:(CGFloat)width;                            // default is 2 pt
+ (void)setRingRadius:(CGFloat)radius;                              // default is 18 pt
+ (void)setRingNoTextRadius:(CGFloat)radius;                        // default is 24 pt
+ (void)setCornerRadius:(CGFloat)cornerRadius;                      // default is 14 pt
+ (void)setBorderColor:(nonnull UIColor*)color;                     // default is nil
+ (void)setBorderWidth:(CGFloat)width;                              // default is 0
+ (void)setFont:(UIFont*)font;                                      // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]
+ (void)setForegroundColor:(UIColor*)color;                         // default is [UIColor blackColor], only used for SVProgressHUDStyleCustom
+ (void)setBackgroundColor:(UIColor*)color;                         // default is [UIColor whiteColor], only used for SVProgressHUDStyleCustom
+ (void)setBackgroundLayerColor:(UIColor*)color;                    // default is [UIColor colorWithWhite:0 alpha:0.4], only used for SVProgressHUDMaskTypeCustom
+ (void)setImageViewSize:(CGSize)size;                              // default is 28x28 pt
+ (void)setInfoImage:(UIImage*)image;                               // default is the bundled info image provided by Freepik
+ (void)setSuccessImage:(UIImage*)image;                            // default is bundled success image from Freepik
+ (void)setErrorImage:(UIImage*)image;                              // default is bundled error image from Freepik
+ (void)setViewForExtension:(UIView*)view;                          // default is nil, only used if #define SV_APP_EXTENSIONS is set
+ (void)setGraceTimeInterval:(NSTimeInterval)interval;              // default is 0 seconds
+ (void)setMinimumDismissTimeInterval:(NSTimeInterval)interval;     // default is 5.0 seconds
+ (void)setMaximumDismissTimeInterval:(NSTimeInterval)interval;     // default is CGFLOAT_MAX
+ (void)setFadeInAnimationDuration:(NSTimeInterval)duration;        // default is 0.15 seconds
+ (void)setFadeOutAnimationDuration:(NSTimeInterval)duration;       // default is 0.15 seconds
+ (void)setMaxSupportedWindowLevel:(UIWindowLevel)windowLevel;      // default is UIWindowLevelNormal
+ (void)setHapticsEnabled:(BOOL)hapticsEnabled;                     // default is NO

樣式

作為標準SVProgressHUD提供兩種預先配置的樣式:

SVProgressHUDStyleLight白色背景黑色圖標和文字
SVProgressHUDStyleDark黑色背景與白色圖標和文本
如果要使用自定義顏色使用setForegroundColorsetBackgroundColor:。這些方法將HUD的風格置為SVProgressHUDStyleCustom

觸覺反饋

對于具有較新設備的用戶(從iPhone 7開始),SVProgressHUD可以根據顯示的HUD來自動觸發觸覺反饋。反饋圖如下:

  • showSuccessWithStatus: < - > UINotificationFeedbackTypeSuccess

  • showInfoWithStatus: < - > UINotificationFeedbackTypeWarning

  • showErrorWithStatus: < - > UINotificationFeedbackTypeError

要啟用此功能,請使用setHapticsEnabled:

具有iPhone 7之前的設備的用戶將不會改變功能。

通知

SVProgressHUD發布四個通知,NSNotificationCenter以響應被顯示/拒絕:

SVProgressHUDWillAppearNotification 提示框即將出現
SVProgressHUDDidAppearNotification 提示框已經出現
SVProgressHUDWillDisappearNotification 提示框即將消失
SVProgressHUDDidDisappearNotification 提示框已經消失

每個通知通過一個userInfo保存HUD狀態字符串(如果有的話)的字典,可以通過檢索SVProgressHUDStatusUserInfoKey

SVProgressHUD SVProgressHUDDidReceiveTouchEventNotification當用戶觸摸整個屏幕或SVProgressHUDDidTouchDownInsideNotification用戶直接觸摸HUD時也會發布。由于此通知userInfo未被傳遞,而對象參數包含UIEvent與觸摸相關的參數。

應用擴展

這里對這個功能不做詳解.自行摸索.

自定義動畫

SVProgressHUD提供了方法可以自定義圖片.但是不支持gif格式,直接利用下面的方法依然顯示一張靜態的圖片

[SVProgressHUD showImage:[UIImage imageNamed:@"loading.gif"] status:@"加載中..."];

我們可以把gif轉化為一個動態的image.
下面是我在百度上搜的一個方法.僅供參考.

#import <UIKit/UIKit.h>

typedef void (^GIFimageBlock)(UIImage *GIFImage);
@interface UIImage (GIFImage)

/** 根據本地GIF圖片名 獲得GIF image對象 */
+ (UIImage *)imageWithGIFNamed:(NSString *)name;

/** 根據一個GIF圖片的data數據 獲得GIF image對象 */
+ (UIImage *)imageWithGIFData:(NSData *)data;

/** 根據一個GIF圖片的URL 獲得GIF image對象 */
+ (void)imageWithGIFUrl:(NSString *)url and:(GIFimageBlock)gifImageBlock;

下面是.m的方法實現.

#import "UIImage+GIFImage.h"
#import <ImageIO/ImageIO.h>
@implementation UIImage (GIFImage)
+ (UIImage *)imageWithGIFData:(NSData *)data{
    
    if (!data) return nil;
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    size_t count = CGImageSourceGetCount(source);
    UIImage *animatedImage;
    if (count <= 1) {
        animatedImage = [[UIImage alloc] initWithData:data];
    } else {
        NSMutableArray *images = [NSMutableArray array];
        NSTimeInterval duration = 0.0f;
        for (size_t i = 0; i < count; i++) {
            // 拿出了Gif的每一幀圖片
            CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL); 
            //Learning... 設置動畫時長 算出每一幀顯示的時長(幀時長)
            NSTimeInterval frameDuration = [UIImage sd_frameDurationAtIndex:i source:source];
            duration += frameDuration;
            // 將每幀圖片添加到數組中
            [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
            // 釋放真圖片對象
            CFRelease(image);
        }
        // 設置動畫時長
        if (!duration) {
            duration = (1.0f / 10.0f) * count; 
        }
        animatedImage = [UIImage animatedImageWithImages:images duration:duration];
    }
    
    // 釋放源Gif圖片
    CFRelease(source);
    return animatedImage;
}
+ (UIImage *)imageWithGIFNamed:(NSString *)name{
    NSUInteger scale = (NSUInteger)[UIScreen mainScreen].scale;
    return [self GIFName:name scale:scale];
}

+ (UIImage *)GIFName:(NSString *)name scale:(NSUInteger)scale{
    NSString *imagePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@@%zdx", name, scale] ofType:@"gif"];  
    if (!imagePath) {
        (scale + 1 > 3) ? (scale -= 1) : (scale += 1);
        imagePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@@%zdx", name, scale] ofType:@"gif"];    
    }
    if (imagePath) {
        // 傳入圖片名(不包含@Nx)
        NSData *imageData = [NSData dataWithContentsOfFile:imagePath];
        return [UIImage imageWithGIFData:imageData];
    } else {
        imagePath = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"];
        if (imagePath) { 
            // 傳入的圖片名已包含@Nx or 傳入圖片只有一張 不分@Nx
            NSData *imageData = [NSData dataWithContentsOfFile:imagePath];
            return [UIImage imageWithGIFData:imageData];
        } else {
            // 不是一張GIF圖片(后綴不是gif)
            return [UIImage imageNamed:name];   
        }  
    }
}
+ (void)imageWithGIFUrl:(NSString *)url and:(GIFimageBlock)gifImageBlock{
    NSURL *GIFUrl = [NSURL URLWithString:url];
    if (!GIFUrl) return;
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSData *CIFData = [NSData dataWithContentsOfURL:GIFUrl];
        // 刷新UI在主線程
        dispatch_async(dispatch_get_main_queue(), ^{
            gifImageBlock([UIImage imageWithGIFData:CIFData]);
        }); 
    });
}
#pragma mark - <關于GIF圖片幀時長(Learning...)>
+ (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
    float frameDuration = 0.1f;
    CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
    NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;
    NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary];
    NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
    if (delayTimeUnclampedProp) {
        frameDuration = [delayTimeUnclampedProp floatValue];
    } 
    else {
        NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
        if (delayTimeProp) {
            frameDuration = [delayTimeProp floatValue];
        }
    }
    // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
    // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
    // a duration of <= 10 ms. See and
    // for more information.
    if (frameDuration < 0.011f) {
        frameDuration = 0.100f;
    }
    CFRelease(cfFrameProperties);
    return frameDuration;
}
@end

這個是UIimage的分類,在用到的控制器里面調用代碼方法即可.這個分類實現我也不太懂.只會用.

   _imgView1.image = [UIImage imageWithGIFNamed:@"xuanxuan"];
    
    NSString *path = [[NSBundle mainBundle] pathForResource:@"xuanxuan" ofType:@"gif"];
    NSData *imgData = [NSData dataWithContentsOfFile:path];
    _imgView2.image = [UIImage imageWithGIFData:imgData];
    
    
    [UIImage imageWithGIFUrl:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1495708809771&di=da92fc5cf3bdd684711ab5124ee43183&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fforum%2Fw%253D580%2Fsign%3D91bd6cd2d42a60595210e1121835342d%2F212eb9389b504fc215d0301ee6dde71190ef6d1a.jpg" and:^(UIImage *GIFImage) {
        _imgView3.image = GIFImage;
    }];
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容