#import <UIKit/UIKit.h>
@interface ProgressHUD : UIView
+ (void)show;
+ (void)dismiss;
+ (void)dismissWithDelay:(NSTimeInterval)delay;
@end
#import "ProgressHUD.h"
#import "CookImageView.h"
#import "CookLabel.h"
#define BOUNDS [[[UIApplication sharedApplication] delegate] window].bounds
@interface ProgressHUD ()
@property (nonatomic, strong) UIView *hudView;
@property (nonatomic, strong) CookLabel *statusLabel;
@property (nonatomic, strong) CookImageView *imageView;
@end
@implementation ProgressHUD
+ (void)show{
[self sharedView];
[[self sharedView] show];
}
+ (void)dismiss{
[[self sharedView] dismissWithDelay:0.0f];
}
+ (void)dismissWithDelay:(NSTimeInterval)delay{
[[self sharedView] dismissWithDelay:delay];
}
+ (ProgressHUD *)sharedView {
static dispatch_once_t onceToken;
static ProgressHUD *sharedView;
dispatch_once(&onceToken, ^{
sharedView = [[self alloc] initWithFrame:BOUNDS];
sharedView.backgroundColor = [UIColor blackColor];
sharedView.alpha = 0.5f;
});
return sharedView;
}
- (void)updateViewHierachy {
NSEnumerator *frontToBackWindows = [UIApplication.sharedApplication.windows reverseObjectEnumerator];
for (UIWindow *window in frontToBackWindows) {
BOOL windowOnMainScreen = window.screen == UIScreen.mainScreen;
BOOL windowIsVisible = !window.hidden && window.alpha > 0;
BOOL windowLevelNormal = window.windowLevel == UIWindowLevelNormal;
if(windowOnMainScreen && windowIsVisible && windowLevelNormal) {
[window addSubview:self.hudView];
break;
}
}
if (!self.superview) {
[self.hudView addSubview:self];
}
}
- (void)registerNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(positionHUD:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
}
- (void)positionHUD:(NSNotification*)notification {
CGRect orientationFrame = BOUNDS;
CGFloat activeHeight = CGRectGetHeight(orientationFrame);
self.hudView.center = CGPointMake(CGRectGetWidth(orientationFrame)/2.0f, floorf(activeHeight*0.45f));
[self.hudView setNeedsDisplay];
}
- (void)show{
__weak ProgressHUD *weakSelf = self;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
__strong ProgressHUD *strongSelf = weakSelf;
if(strongSelf){
[strongSelf updateViewHierachy];
strongSelf.imageView.image = [[UIImage imageNamed:@"loadingIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
strongSelf.statusLabel.text = @"读取中...";
[strongSelf positionHUD:nil];
[strongSelf registerNotifications];
}
}];
}
- (UIView*)hudView {
if(!_hudView) {
_hudView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 82, 105)];
_hudView.layer.masksToBounds = YES;
_hudView.layer.cornerRadius = 6.0f;
_hudView.backgroundColor = [UIColor clearColor];
}
return _hudView;
}
- (CookLabel *)statusLabel {
_statusLabel = [CookLabel onlyOneLabel];
_statusLabel.frame = CGRectMake(0, 80, 82, 25);
_statusLabel.textAlignment = NSTextAlignmentCenter;
_statusLabel.textColor = [UIColor whiteColor];
_statusLabel.font = [UIFont systemFontOfSize:12.0f];
if (!_statusLabel.superview) {
[self.hudView addSubview:_statusLabel];
}
return _statusLabel;
}
- (CookImageView *)imageView{
_imageView = [CookImageView onlyOneImage];
_imageView.frame = CGRectMake(5, 5, 72, 72);
if (!_imageView.superview) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
animation.fromValue = (id) 0;
animation.toValue = @(M_PI*2);
animation.duration = 1.0f;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
animation.removedOnCompletion = NO;
animation.repeatCount = INFINITY;
animation.fillMode = kCAFillModeForwards;
animation.autoreverses = NO;
[_imageView.layer addAnimation:animation forKey:@"rotate"];
[self.hudView addSubview:_imageView];
}
return _imageView;
}
- (void)dismissWithDelay:(NSTimeInterval)delay{
__weak ProgressHUD *weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
__strong ProgressHUD *strongSelf = weakSelf;
if(strongSelf){
[_statusLabel removeFromSuperview];
[_imageView removeFromSuperview];
[_hudView removeFromSuperview];
[strongSelf removeFromSuperview];
[[NSNotificationCenter defaultCenter] removeObserver:strongSelf];
}
});
}
@end
@interface CookImageView : UIImageView
+ (instancetype)onlyOneImage;
@end
#import "CookImageView.h"
static CookImageView *_imageView;
@implementation CookImageView
+ (instancetype)onlyOneImage{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_imageView = [[self alloc] init];
});
return _imageView;
}
+(instancetype)allocWithZone:(struct _NSZone *)zone{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_imageView = [super allocWithZone:zone];
});
return _imageView;
}
@end
#import <UIKit/UIKit.h>
@interface CookLabel : UILabel
+ (instancetype)onlyOneLabel;
@end
#import "CookLabel.h"
static CookLabel *_label;
@implementation CookLabel
+ (instancetype)onlyOneLabel{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_label = [[CookLabel alloc] init];
});
return _label;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_label = [super allocWithZone:zone];
});
return _label;
}
@end