mirror of
https://github.com/leanote/leanote-ios.git
synced 2026-01-28 01:09:05 +08:00
1031 lines
35 KiB
Objective-C
1031 lines
35 KiB
Objective-C
//
|
|
// SVProgressHUD.m
|
|
//
|
|
// Copyright 2011-2014 Sam Vermette. All rights reserved.
|
|
//
|
|
// https://github.com/samvermette/SVProgressHUD
|
|
|
|
// life修改, 为什么要修改, 因为两套不同的loading和showSuccess样式不一样!!
|
|
// 两个sharedView, is2=NO
|
|
// sharedView2(for loading), is2=YES
|
|
//
|
|
|
|
#if !__has_feature(objc_arc)
|
|
#error SVProgressHUD is ARC only. Either turn on ARC for the project or use -fobjc-arc flag
|
|
#endif
|
|
|
|
#import "SVProgressHUD.h"
|
|
#import "SVIndefiniteAnimatedView.h"
|
|
#import <QuartzCore/QuartzCore.h>
|
|
|
|
NSString * const SVProgressHUDDidReceiveTouchEventNotification = @"SVProgressHUDDidReceiveTouchEventNotification";
|
|
NSString * const SVProgressHUDDidTouchDownInsideNotification = @"SVProgressHUDDidTouchDownInsideNotification";
|
|
NSString * const SVProgressHUDWillDisappearNotification = @"SVProgressHUDWillDisappearNotification";
|
|
NSString * const SVProgressHUDDidDisappearNotification = @"SVProgressHUDDidDisappearNotification";
|
|
NSString * const SVProgressHUDWillAppearNotification = @"SVProgressHUDWillAppearNotification";
|
|
NSString * const SVProgressHUDDidAppearNotification = @"SVProgressHUDDidAppearNotification";
|
|
|
|
NSString * const SVProgressHUDStatusUserInfoKey = @"SVProgressHUDStatusUserInfoKey";
|
|
|
|
static UIColor *SVProgressHUDBackgroundColor;
|
|
static UIColor *SVProgressHUDForegroundColor;
|
|
|
|
static UIColor *SVProgressHUDBackgroundColor2;
|
|
static UIColor *SVProgressHUDForegroundColor2;
|
|
|
|
static CGFloat SVProgressHUDRingThickness;
|
|
static UIFont *SVProgressHUDFont;
|
|
static UIImage *SVProgressHUDInfoImage;
|
|
static UIImage *SVProgressHUDSuccessImage;
|
|
static UIImage *SVProgressHUDErrorImage;
|
|
static SVProgressHUDMaskType SVProgressHUDDefaultMaskType;
|
|
static UIView *SVProgressHUDExtensionView;
|
|
|
|
static const CGFloat SVProgressHUDRingRadius = 18;
|
|
static const CGFloat SVProgressHUDRingNoTextRadius = 24;
|
|
static const CGFloat SVProgressHUDParallaxDepthPoints = 10;
|
|
static const CGFloat SVProgressHUDUndefinedProgress = -1;
|
|
|
|
@interface SVProgressHUD ()
|
|
|
|
@property (nonatomic, readwrite) SVProgressHUDMaskType maskType;
|
|
@property (nonatomic, strong, readonly) NSTimer *fadeOutTimer;
|
|
@property (nonatomic, readonly, getter = isClear) BOOL clear;
|
|
|
|
@property (nonatomic, strong) UIControl *overlayView;
|
|
@property (nonatomic, strong) UIView *hudView;
|
|
@property (nonatomic, strong) UILabel *stringLabel;
|
|
@property (nonatomic, strong) UIImageView *imageView;
|
|
@property (nonatomic, strong) SVIndefiniteAnimatedView *indefiniteAnimatedView;
|
|
|
|
@property (nonatomic, readwrite) CGFloat progress;
|
|
@property (nonatomic, readwrite) NSUInteger activityCount;
|
|
@property (nonatomic, strong) CAShapeLayer *backgroundRingLayer;
|
|
@property (nonatomic, strong) CAShapeLayer *ringLayer;
|
|
|
|
@property (nonatomic, readonly) CGFloat visibleKeyboardHeight;
|
|
@property (nonatomic, assign) UIOffset offsetFromCenter;
|
|
|
|
@property BOOL is2;
|
|
|
|
- (void)showProgress:(float)progress status:(NSString*)string maskType:(SVProgressHUDMaskType)hudMaskType;
|
|
- (void)showImage:(UIImage*)image status:(NSString*)status duration:(NSTimeInterval)duration maskType:(SVProgressHUDMaskType)hudMaskType;
|
|
|
|
- (void)dismiss;
|
|
|
|
- (void)setStatus:(NSString*)string;
|
|
- (void)registerNotifications;
|
|
- (NSDictionary *)notificationUserInfo;
|
|
- (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle;
|
|
- (void)positionHUD:(NSNotification*)notification;
|
|
- (NSTimeInterval)displayDurationForString:(NSString*)string;
|
|
|
|
@end
|
|
|
|
|
|
@implementation SVProgressHUD
|
|
|
|
+ (SVProgressHUD*)sharedView {
|
|
static dispatch_once_t once;
|
|
static SVProgressHUD *sharedView;
|
|
dispatch_once(&once, ^ { sharedView = [[self alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; });
|
|
return sharedView;
|
|
}
|
|
|
|
// for progress loading
|
|
+ (SVProgressHUD*)sharedView2 {
|
|
static dispatch_once_t once2;
|
|
static SVProgressHUD *sharedView2;
|
|
dispatch_once(&once2, ^ { sharedView2 = [[self alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; });
|
|
sharedView2.is2 = YES;
|
|
return sharedView2;
|
|
}
|
|
|
|
#pragma mark - Setters
|
|
|
|
+ (void)setStatus:(NSString *)string {
|
|
[[self sharedView] setStatus:string];
|
|
}
|
|
|
|
+ (void)setBackgroundColor:(UIColor *)color {
|
|
[self sharedView].hudView.backgroundColor = color;
|
|
SVProgressHUDBackgroundColor = color;
|
|
}
|
|
|
|
+ (void)setForegroundColor:(UIColor *)color {
|
|
[self sharedView];
|
|
SVProgressHUDForegroundColor = color;
|
|
}
|
|
|
|
// for progress loading
|
|
+ (void)setBackgroundColor2:(UIColor *)color {
|
|
[self sharedView2].hudView.backgroundColor = color;
|
|
SVProgressHUDBackgroundColor2 = color;
|
|
}
|
|
+ (void)setForegroundColor2:(UIColor *)color {
|
|
[self sharedView2];
|
|
SVProgressHUDForegroundColor2 = color;
|
|
}
|
|
|
|
+ (void)setFont:(UIFont *)font {
|
|
[self sharedView];
|
|
SVProgressHUDFont = font;
|
|
}
|
|
|
|
+ (void)setRingThickness:(CGFloat)width {
|
|
[self sharedView];
|
|
SVProgressHUDRingThickness = width;
|
|
}
|
|
|
|
+ (void)setInfoImage:(UIImage*)image{
|
|
[self sharedView];
|
|
SVProgressHUDInfoImage = image;
|
|
}
|
|
|
|
+ (void)setSuccessImage:(UIImage *)image {
|
|
[self sharedView];
|
|
SVProgressHUDSuccessImage = image;
|
|
}
|
|
|
|
+ (void)setErrorImage:(UIImage *)image {
|
|
[self sharedView];
|
|
SVProgressHUDErrorImage = image;
|
|
}
|
|
|
|
+ (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType{
|
|
[self sharedView];
|
|
SVProgressHUDDefaultMaskType = maskType;
|
|
}
|
|
|
|
+ (void)setViewForExtension:(UIView *)view{
|
|
[self sharedView];
|
|
SVProgressHUDExtensionView = view;
|
|
}
|
|
|
|
|
|
#pragma mark - Show Methods
|
|
|
|
// loading
|
|
+ (void)show {
|
|
// [self showWithStatus:nil];
|
|
|
|
[self sharedView2];
|
|
[self showProgress:SVProgressHUDUndefinedProgress status:nil maskType:SVProgressHUDDefaultMaskType use2:YES];
|
|
}
|
|
|
|
+ (void)showWithMaskType:(SVProgressHUDMaskType)maskType {
|
|
[self showProgress:SVProgressHUDUndefinedProgress maskType:maskType];
|
|
}
|
|
|
|
+ (void)showWithStatus:(NSString *)status {
|
|
[self showProgress:SVProgressHUDUndefinedProgress status:status];
|
|
}
|
|
|
|
+ (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType {
|
|
[self showProgress:SVProgressHUDUndefinedProgress status:status maskType:maskType];
|
|
}
|
|
|
|
// 用2
|
|
+ (void)showProgress:(float)progress {
|
|
[self sharedView2];
|
|
// [self showProgress:progress maskType:SVProgressHUDDefaultMaskType];
|
|
[self showProgress:progress status:nil maskType:SVProgressHUDDefaultMaskType use2:YES];
|
|
}
|
|
|
|
+ (void)showProgress:(float)progress maskType:(SVProgressHUDMaskType)maskType{
|
|
[self showProgress:progress status:nil maskType:maskType use2:NO];
|
|
}
|
|
|
|
// 用1
|
|
+ (void)showProgress:(float)progress status:(NSString *)status {
|
|
[self sharedView];
|
|
[self showProgress:progress status:status maskType:SVProgressHUDDefaultMaskType use2:NO];
|
|
}
|
|
|
|
+ (void)showProgress:(float)progress status:(NSString *)status maskType:(SVProgressHUDMaskType)maskType use2:(BOOL)use2 {
|
|
|
|
if(!use2) {
|
|
[[self sharedView] showProgress:progress status:status maskType:maskType];
|
|
}
|
|
else {
|
|
[[self sharedView2] showProgress:progress status:status maskType:maskType];
|
|
}
|
|
}
|
|
|
|
|
|
#pragma mark - Show then dismiss methods
|
|
|
|
+ (void)showInfoWithStatus:(NSString *)string {
|
|
[self sharedView];
|
|
[self showInfoWithStatus:string maskType:SVProgressHUDDefaultMaskType];
|
|
}
|
|
|
|
+ (void)showInfoWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType {
|
|
[self sharedView];
|
|
[self showImage:SVProgressHUDInfoImage status:string maskType:maskType];
|
|
}
|
|
|
|
+ (void)showSuccessWithStatus:(NSString *)string {
|
|
[self sharedView];
|
|
[self showSuccessWithStatus:string maskType:SVProgressHUDDefaultMaskType];
|
|
}
|
|
|
|
+ (void)showSuccessWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType {
|
|
[self sharedView];
|
|
[self showImage:SVProgressHUDSuccessImage status:string maskType:maskType];
|
|
}
|
|
|
|
+ (void)showErrorWithStatus:(NSString *)string {
|
|
[self sharedView];
|
|
[self showErrorWithStatus:string maskType:SVProgressHUDDefaultMaskType];
|
|
}
|
|
|
|
+ (void)showErrorWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType {
|
|
[self sharedView];
|
|
[self showImage:SVProgressHUDErrorImage status:string maskType:maskType];
|
|
}
|
|
|
|
+ (void)showImage:(UIImage *)image status:(NSString *)string {
|
|
[self sharedView];
|
|
[self showImage:image status:string maskType:SVProgressHUDDefaultMaskType];
|
|
}
|
|
|
|
+ (void)showImage:(UIImage *)image status:(NSString *)string maskType:(SVProgressHUDMaskType)maskType {
|
|
NSTimeInterval displayInterval = [[self sharedView] displayDurationForString:string];
|
|
[[self sharedView] showImage:image status:string duration:displayInterval maskType:maskType];
|
|
}
|
|
|
|
|
|
#pragma mark - Dismiss Methods
|
|
|
|
+ (void)popActivity {
|
|
if([self sharedView].activityCount > 0)
|
|
[self sharedView].activityCount--;
|
|
if([self sharedView].activityCount == 0)
|
|
[[self sharedView] dismiss];
|
|
}
|
|
|
|
+ (void)dismiss {
|
|
if ([self isVisible]) {
|
|
[[self sharedView] dismiss];
|
|
}
|
|
|
|
if ([self isVisible2]) {
|
|
[[self sharedView2] dismiss];
|
|
}
|
|
}
|
|
|
|
#pragma mark - Offset
|
|
|
|
+ (void)setOffsetFromCenter:(UIOffset)offset {
|
|
[self sharedView].offsetFromCenter = offset;
|
|
}
|
|
|
|
+ (void)resetOffsetFromCenter {
|
|
[self setOffsetFromCenter:UIOffsetZero];
|
|
}
|
|
|
|
#pragma mark - Instance Methods
|
|
|
|
- (id)initWithFrame:(CGRect)frame {
|
|
if ((self = [super initWithFrame:frame])) {
|
|
self.userInteractionEnabled = NO;
|
|
self.backgroundColor = [UIColor clearColor];
|
|
self.alpha = 0.0f;
|
|
self.activityCount = 0;
|
|
|
|
// SVProgressHUDBackgroundColor = [UIColor whiteColor];
|
|
// SVProgressHUDForegroundColor = [UIColor blackColor];
|
|
if ([UIFont respondsToSelector:@selector(preferredFontForTextStyle:)]) {
|
|
SVProgressHUDFont = [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline];
|
|
} else {
|
|
SVProgressHUDFont = [UIFont systemFontOfSize:14.0f];
|
|
// SVProgressHUDBackgroundColor = [UIColor colorWithWhite:0.0f alpha:0.8f];
|
|
// SVProgressHUDForegroundColor = [UIColor whiteColor];
|
|
}
|
|
|
|
NSBundle *bundle = [NSBundle bundleForClass:self.class];
|
|
NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"];
|
|
NSBundle *imageBundle = [NSBundle bundleWithURL:url];
|
|
|
|
UIImage* infoImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"info" ofType:@"png"]];
|
|
UIImage* successImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"success" ofType:@"png"]];
|
|
UIImage* errorImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"error" ofType:@"png"]];
|
|
|
|
if ([[UIImage class] instancesRespondToSelector:@selector(imageWithRenderingMode:)]) {
|
|
SVProgressHUDInfoImage = [infoImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
|
// SVProgressHUDSuccessImage = [successImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
|
// SVProgressHUDErrorImage = [errorImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
|
} else {
|
|
SVProgressHUDInfoImage = infoImage;
|
|
// SVProgressHUDSuccessImage = successImage;
|
|
// SVProgressHUDErrorImage = errorImage;
|
|
}
|
|
|
|
SVProgressHUDRingThickness = 2;
|
|
SVProgressHUDDefaultMaskType = SVProgressHUDMaskTypeNone;
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)drawRect:(CGRect)rect {
|
|
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
|
|
switch (self.maskType) {
|
|
case SVProgressHUDMaskTypeBlack: {
|
|
|
|
[[UIColor colorWithWhite:0 alpha:0.5] set];
|
|
CGContextFillRect(context, self.bounds);
|
|
|
|
break;
|
|
}
|
|
case SVProgressHUDMaskTypeGradient: {
|
|
|
|
size_t locationsCount = 2;
|
|
CGFloat locations[2] = {0.0f, 1.0f};
|
|
CGFloat colors[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.75f};
|
|
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
|
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount);
|
|
CGColorSpaceRelease(colorSpace);
|
|
|
|
CGFloat freeHeight = CGRectGetHeight(self.bounds) - self.visibleKeyboardHeight;
|
|
|
|
CGPoint center = CGPointMake(CGRectGetWidth(self.bounds)/2, freeHeight/2);
|
|
float radius = MIN(CGRectGetWidth(self.bounds) , CGRectGetHeight(self.bounds)) ;
|
|
CGContextDrawRadialGradient (context, gradient, center, 0, center, radius, kCGGradientDrawsAfterEndLocation);
|
|
CGGradientRelease(gradient);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
- (void)updatePosition {
|
|
|
|
CGFloat hudWidth = 100.0f;
|
|
CGFloat hudHeight = 100.0f;
|
|
CGFloat stringHeightBuffer = 20.0f;
|
|
CGFloat stringAndContentHeightBuffer = 80.0f;
|
|
|
|
CGFloat stringWidth = 0.0f;
|
|
CGFloat stringHeight = 0.0f;
|
|
CGRect labelRect = CGRectZero;
|
|
|
|
NSString *string = self.stringLabel.text;
|
|
|
|
// Check if an image or progress ring is displayed
|
|
BOOL imageUsed = (self.imageView.image) || (self.imageView.hidden);
|
|
BOOL progressUsed = (self.progress != SVProgressHUDUndefinedProgress) && (self.progress >= 0.0f);
|
|
|
|
if(string) {
|
|
CGSize constraintSize = CGSizeMake(200.0f, 300.0f);
|
|
CGRect stringRect;
|
|
if ([string respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
|
|
stringRect = [string boundingRectWithSize:constraintSize
|
|
options:(NSStringDrawingUsesFontLeading|NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin)
|
|
attributes:@{NSFontAttributeName: self.stringLabel.font}
|
|
context:NULL];
|
|
} else {
|
|
CGSize stringSize;
|
|
|
|
if ([string respondsToSelector:@selector(sizeWithAttributes:)])
|
|
stringSize = [string sizeWithAttributes:@{NSFontAttributeName:[UIFont fontWithName:self.stringLabel.font.fontName size:self.stringLabel.font.pointSize]}];
|
|
else
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wdeprecated"
|
|
stringSize = [string sizeWithFont:self.stringLabel.font constrainedToSize:CGSizeMake(200.0f, 300.0f)];
|
|
#pragma clang diagnostic pop
|
|
|
|
stringRect = CGRectMake(0.0f, 0.0f, stringSize.width, stringSize.height);
|
|
}
|
|
stringWidth = stringRect.size.width;
|
|
stringHeight = ceil(CGRectGetHeight(stringRect));
|
|
|
|
if (imageUsed || progressUsed)
|
|
hudHeight = stringAndContentHeightBuffer + stringHeight;
|
|
else
|
|
hudHeight = stringHeightBuffer + stringHeight;
|
|
|
|
if(stringWidth > hudWidth)
|
|
hudWidth = ceil(stringWidth/2)*2;
|
|
|
|
CGFloat labelRectY = (imageUsed || progressUsed) ? 68.0f : 9.0f;
|
|
|
|
if(hudHeight > 100.0f) {
|
|
labelRect = CGRectMake(12.0f, labelRectY, hudWidth, stringHeight);
|
|
hudWidth += 24.0f;
|
|
} else {
|
|
hudWidth += 24.0f;
|
|
labelRect = CGRectMake(0.0f, labelRectY, hudWidth, stringHeight);
|
|
}
|
|
}
|
|
|
|
self.hudView.bounds = CGRectMake(0.0f, 0.0f, hudWidth, hudHeight);
|
|
|
|
if(string)
|
|
self.imageView.center = CGPointMake(CGRectGetWidth(self.hudView.bounds)/2, 36.0f);
|
|
else
|
|
self.imageView.center = CGPointMake(CGRectGetWidth(self.hudView.bounds)/2, CGRectGetHeight(self.hudView.bounds)/2);
|
|
|
|
self.stringLabel.hidden = NO;
|
|
self.stringLabel.frame = labelRect;
|
|
|
|
[CATransaction begin];
|
|
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
|
|
|
|
if(string) {
|
|
self.indefiniteAnimatedView.radius = SVProgressHUDRingRadius;
|
|
[self.indefiniteAnimatedView sizeToFit];
|
|
|
|
CGPoint center = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), 36.0f);
|
|
self.indefiniteAnimatedView.center = center;
|
|
|
|
if(self.progress != SVProgressHUDUndefinedProgress)
|
|
self.backgroundRingLayer.position = self.ringLayer.position = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), 36.0f);
|
|
} else {
|
|
self.indefiniteAnimatedView.radius = SVProgressHUDRingNoTextRadius;
|
|
[self.indefiniteAnimatedView sizeToFit];
|
|
|
|
CGPoint center = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), CGRectGetHeight(self.hudView.bounds)/2);
|
|
self.indefiniteAnimatedView.center = center;
|
|
|
|
if(self.progress != SVProgressHUDUndefinedProgress)
|
|
self.backgroundRingLayer.position = self.ringLayer.position = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), CGRectGetHeight(self.hudView.bounds)/2);
|
|
}
|
|
|
|
[CATransaction commit];
|
|
}
|
|
|
|
- (void)setStatus:(NSString *)string {
|
|
self.stringLabel.text = string;
|
|
[self updatePosition];
|
|
|
|
}
|
|
|
|
- (void)setFadeOutTimer:(NSTimer *)newTimer {
|
|
if(_fadeOutTimer)
|
|
[_fadeOutTimer invalidate], _fadeOutTimer = nil;
|
|
|
|
if(newTimer)
|
|
_fadeOutTimer = newTimer;
|
|
}
|
|
|
|
|
|
- (void)registerNotifications {
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(positionHUD:)
|
|
name:UIApplicationDidChangeStatusBarOrientationNotification
|
|
object:nil];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(positionHUD:)
|
|
name:UIKeyboardWillHideNotification
|
|
object:nil];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(positionHUD:)
|
|
name:UIKeyboardDidHideNotification
|
|
object:nil];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(positionHUD:)
|
|
name:UIKeyboardWillShowNotification
|
|
object:nil];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(positionHUD:)
|
|
name:UIKeyboardDidShowNotification
|
|
object:nil];
|
|
}
|
|
|
|
|
|
- (NSDictionary *)notificationUserInfo{
|
|
return (self.stringLabel.text ? @{SVProgressHUDStatusUserInfoKey : self.stringLabel.text} : nil);
|
|
}
|
|
|
|
|
|
- (void)positionHUD:(NSNotification*)notification {
|
|
|
|
CGFloat keyboardHeight = 0.0f;
|
|
double animationDuration = 0.0;
|
|
|
|
self.frame = UIScreen.mainScreen.bounds;
|
|
|
|
#if !defined(SV_APP_EXTENSIONS)
|
|
UIInterfaceOrientation orientation = UIApplication.sharedApplication.statusBarOrientation;
|
|
#else
|
|
UIInterfaceOrientation orientation = CGRectGetWidth(self.frame) > CGRectGetHeight(self.frame) ? UIInterfaceOrientationLandscapeLeft : UIInterfaceOrientationPortrait;
|
|
#endif
|
|
// no transforms applied to window in iOS 8, but only if compiled with iOS 8 sdk as base sdk, otherwise system supports old rotation logic.
|
|
BOOL ignoreOrientation = NO;
|
|
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
|
|
if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) {
|
|
ignoreOrientation = YES;
|
|
}
|
|
#endif
|
|
|
|
if(notification) {
|
|
NSDictionary* keyboardInfo = [notification userInfo];
|
|
CGRect keyboardFrame = [[keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
|
|
animationDuration = [[keyboardInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
|
|
|
|
if(notification.name == UIKeyboardWillShowNotification || notification.name == UIKeyboardDidShowNotification) {
|
|
if(ignoreOrientation || UIInterfaceOrientationIsPortrait(orientation))
|
|
keyboardHeight = CGRectGetHeight(keyboardFrame);
|
|
else
|
|
keyboardHeight = CGRectGetWidth(keyboardFrame);
|
|
}
|
|
} else {
|
|
keyboardHeight = self.visibleKeyboardHeight;
|
|
}
|
|
|
|
CGRect orientationFrame = self.bounds;
|
|
#if !defined(SV_APP_EXTENSIONS)
|
|
CGRect statusBarFrame = UIApplication.sharedApplication.statusBarFrame;
|
|
#else
|
|
CGRect statusBarFrame = CGRectZero;
|
|
#endif
|
|
|
|
if(!ignoreOrientation && UIInterfaceOrientationIsLandscape(orientation)) {
|
|
float temp = CGRectGetWidth(orientationFrame);
|
|
orientationFrame.size.width = CGRectGetHeight(orientationFrame);
|
|
orientationFrame.size.height = temp;
|
|
|
|
temp = CGRectGetWidth(statusBarFrame);
|
|
statusBarFrame.size.width = CGRectGetHeight(statusBarFrame);
|
|
statusBarFrame.size.height = temp;
|
|
}
|
|
|
|
CGFloat activeHeight = CGRectGetHeight(orientationFrame);
|
|
|
|
if(keyboardHeight > 0)
|
|
activeHeight += CGRectGetHeight(statusBarFrame)*2;
|
|
|
|
activeHeight -= keyboardHeight;
|
|
CGFloat posY = floor(activeHeight*0.45);
|
|
CGFloat posX = CGRectGetWidth(orientationFrame)/2;
|
|
|
|
CGPoint newCenter;
|
|
CGFloat rotateAngle;
|
|
|
|
if (ignoreOrientation) {
|
|
rotateAngle = 0.0;
|
|
newCenter = CGPointMake(posX, posY);
|
|
} else {
|
|
switch (orientation) {
|
|
case UIInterfaceOrientationPortraitUpsideDown:
|
|
rotateAngle = M_PI;
|
|
newCenter = CGPointMake(posX, CGRectGetHeight(orientationFrame)-posY);
|
|
break;
|
|
case UIInterfaceOrientationLandscapeLeft:
|
|
rotateAngle = -M_PI/2.0f;
|
|
newCenter = CGPointMake(posY, posX);
|
|
break;
|
|
case UIInterfaceOrientationLandscapeRight:
|
|
rotateAngle = M_PI/2.0f;
|
|
newCenter = CGPointMake(CGRectGetHeight(orientationFrame)-posY, posX);
|
|
break;
|
|
default: // as UIInterfaceOrientationPortrait
|
|
rotateAngle = 0.0;
|
|
newCenter = CGPointMake(posX, posY);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(notification) {
|
|
[UIView animateWithDuration:animationDuration
|
|
delay:0
|
|
options:UIViewAnimationOptionAllowUserInteraction
|
|
animations:^{
|
|
[self moveToPoint:newCenter rotateAngle:rotateAngle];
|
|
[self.hudView setNeedsDisplay];
|
|
} completion:NULL];
|
|
} else {
|
|
[self moveToPoint:newCenter rotateAngle:rotateAngle];
|
|
[self.hudView setNeedsDisplay];
|
|
}
|
|
|
|
}
|
|
|
|
- (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle {
|
|
self.hudView.transform = CGAffineTransformMakeRotation(angle);
|
|
self.hudView.center = CGPointMake(newCenter.x + self.offsetFromCenter.horizontal, newCenter.y + self.offsetFromCenter.vertical);
|
|
}
|
|
|
|
- (void)overlayViewDidReceiveTouchEvent:(id)sender forEvent:(UIEvent *)event {
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidReceiveTouchEventNotification object:event];
|
|
|
|
UITouch *touch = event.allTouches.anyObject;
|
|
CGPoint touchLocation = [touch locationInView:self];
|
|
|
|
if (CGRectContainsPoint(self.hudView.frame, touchLocation)) {
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidTouchDownInsideNotification object:event];
|
|
}
|
|
}
|
|
|
|
|
|
#pragma mark - Master show/dismiss methods
|
|
|
|
- (void)showProgress:(float)progress status:(NSString*)string maskType:(SVProgressHUDMaskType)hudMaskType {
|
|
if(!self.overlayView.superview){
|
|
#if !defined(SV_APP_EXTENSIONS)
|
|
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.overlayView];
|
|
break;
|
|
}
|
|
}
|
|
#else
|
|
if(SVProgressHUDExtensionView){
|
|
[SVProgressHUDExtensionView addSubview:self.overlayView];
|
|
}
|
|
#endif
|
|
} else {
|
|
// Ensure that overlay will be exactly on top of rootViewController (which may be changed during runtime).
|
|
[self.overlayView.superview bringSubviewToFront:self.overlayView];
|
|
}
|
|
|
|
if(!self.superview)
|
|
[self.overlayView addSubview:self];
|
|
|
|
self.fadeOutTimer = nil;
|
|
self.imageView.hidden = YES;
|
|
self.maskType = hudMaskType;
|
|
self.progress = progress;
|
|
|
|
self.stringLabel.text = string;
|
|
[self updatePosition];
|
|
|
|
if(progress >= 0) {
|
|
self.imageView.image = nil;
|
|
self.imageView.hidden = NO;
|
|
[self.indefiniteAnimatedView removeFromSuperview];
|
|
|
|
self.ringLayer.strokeEnd = progress;
|
|
|
|
if(progress == 0)
|
|
self.activityCount++;
|
|
} else {
|
|
self.activityCount++;
|
|
[self cancelRingLayerAnimation];
|
|
[self.hudView addSubview:self.indefiniteAnimatedView];
|
|
}
|
|
|
|
if(self.maskType != SVProgressHUDMaskTypeNone) {
|
|
self.overlayView.userInteractionEnabled = YES;
|
|
self.accessibilityLabel = string;
|
|
self.isAccessibilityElement = YES;
|
|
} else {
|
|
self.overlayView.userInteractionEnabled = NO;
|
|
self.hudView.accessibilityLabel = string;
|
|
self.hudView.isAccessibilityElement = YES;
|
|
}
|
|
|
|
[self.overlayView setHidden:NO];
|
|
self.overlayView.backgroundColor = [UIColor clearColor];
|
|
[self positionHUD:nil];
|
|
|
|
if(self.alpha != 1 || self.hudView.alpha != 1) {
|
|
NSDictionary *userInfo = [self notificationUserInfo];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDWillAppearNotification
|
|
object:nil
|
|
userInfo:userInfo];
|
|
|
|
[self registerNotifications];
|
|
self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 1.3, 1.3);
|
|
|
|
if(self.isClear) {
|
|
self.alpha = 1;
|
|
self.hudView.alpha = 0;
|
|
}
|
|
|
|
[UIView animateWithDuration:0.15
|
|
delay:0
|
|
options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState
|
|
animations:^{
|
|
self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 1/1.3, 1/1.3);
|
|
|
|
if(self.isClear) // handle iOS 7 and 8 UIToolbar which not answers well to hierarchy opacity change
|
|
self.hudView.alpha = 1;
|
|
else
|
|
self.alpha = 1;
|
|
}
|
|
completion:^(BOOL finished){
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidAppearNotification
|
|
object:nil
|
|
userInfo:userInfo];
|
|
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);
|
|
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, string);
|
|
}];
|
|
|
|
[self setNeedsDisplay];
|
|
}
|
|
}
|
|
|
|
- (UIImage *)image:(UIImage *)image withTintColor:(UIColor *)color{
|
|
CGRect rect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);
|
|
UIGraphicsBeginImageContextWithOptions(rect.size, NO, image.scale);
|
|
CGContextRef c = UIGraphicsGetCurrentContext();
|
|
[image drawInRect:rect];
|
|
CGContextSetFillColorWithColor(c, [color CGColor]);
|
|
CGContextSetBlendMode(c, kCGBlendModeSourceAtop);
|
|
CGContextFillRect(c, rect);
|
|
UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
UIGraphicsEndImageContext();
|
|
|
|
return tintedImage;
|
|
}
|
|
|
|
- (void)showImage:(UIImage *)image status:(NSString *)string duration:(NSTimeInterval)duration maskType:(SVProgressHUDMaskType)hudMaskType {
|
|
self.progress = SVProgressHUDUndefinedProgress;
|
|
self.maskType = hudMaskType;
|
|
[self cancelRingLayerAnimation];
|
|
|
|
if(![self.class isVisible])
|
|
[self.class showWithMaskType:self.maskType];
|
|
|
|
if ([self.imageView respondsToSelector:@selector(setTintColor:)]) {
|
|
self.imageView.tintColor = self.is2 ? SVProgressHUDForegroundColor2 : SVProgressHUDForegroundColor ;
|
|
} else {
|
|
image = [self image:image withTintColor:self.is2 ? SVProgressHUDForegroundColor2 : SVProgressHUDForegroundColor ];
|
|
}
|
|
self.imageView.image = image;
|
|
self.imageView.hidden = NO;
|
|
|
|
self.stringLabel.text = string;
|
|
[self updatePosition];
|
|
[self.indefiniteAnimatedView removeFromSuperview];
|
|
|
|
if(self.maskType != SVProgressHUDMaskTypeNone) {
|
|
self.overlayView.userInteractionEnabled = YES;
|
|
self.accessibilityLabel = string;
|
|
self.isAccessibilityElement = YES;
|
|
} else {
|
|
self.overlayView.userInteractionEnabled = NO;
|
|
self.hudView.accessibilityLabel = string;
|
|
self.hudView.isAccessibilityElement = YES;
|
|
}
|
|
|
|
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);
|
|
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, string);
|
|
|
|
self.fadeOutTimer = [NSTimer timerWithTimeInterval:duration target:self selector:@selector(dismiss) userInfo:nil repeats:NO];
|
|
[[NSRunLoop mainRunLoop] addTimer:self.fadeOutTimer forMode:NSRunLoopCommonModes];
|
|
}
|
|
|
|
- (void)dismiss {
|
|
NSDictionary *userInfo = [self notificationUserInfo];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDWillDisappearNotification
|
|
object:nil
|
|
userInfo:userInfo];
|
|
|
|
self.activityCount = 0;
|
|
[UIView animateWithDuration:0.15
|
|
delay:0
|
|
options:UIViewAnimationCurveEaseIn | UIViewAnimationOptionAllowUserInteraction
|
|
animations:^{
|
|
self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 0.8f, 0.8f);
|
|
if(self.isClear) // handle iOS 7 UIToolbar not answer well to hierarchy opacity change
|
|
self.hudView.alpha = 0.0f;
|
|
else
|
|
self.alpha = 0.0f;
|
|
}
|
|
completion:^(BOOL finished){
|
|
if(self.alpha == 0.0f || self.hudView.alpha == 0.0f) {
|
|
self.alpha = 0.0f;
|
|
self.hudView.alpha = 0.0f;
|
|
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
[self cancelRingLayerAnimation];
|
|
[_hudView removeFromSuperview];
|
|
_hudView = nil;
|
|
|
|
[_overlayView removeFromSuperview];
|
|
_overlayView = nil;
|
|
|
|
[_indefiniteAnimatedView removeFromSuperview];
|
|
_indefiniteAnimatedView = nil;
|
|
|
|
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil);
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidDisappearNotification
|
|
object:nil
|
|
userInfo:userInfo];
|
|
|
|
// Tell the rootViewController to update the StatusBar appearance
|
|
#if !defined(SV_APP_EXTENSIONS)
|
|
UIViewController *rootController = [[UIApplication sharedApplication] keyWindow].rootViewController;
|
|
if ([rootController respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
|
|
[rootController setNeedsStatusBarAppearanceUpdate];
|
|
}
|
|
#endif
|
|
// uncomment to make sure UIWindow is gone from app.windows
|
|
//NSLog(@"%@", [UIApplication sharedApplication].windows);
|
|
//NSLog(@"keyWindow = %@", [UIApplication sharedApplication].keyWindow);
|
|
}
|
|
}];
|
|
}
|
|
|
|
|
|
#pragma mark - Ring progress animation
|
|
|
|
- (SVIndefiniteAnimatedView *)indefiniteAnimatedView {
|
|
if (_indefiniteAnimatedView == nil) {
|
|
_indefiniteAnimatedView = [[SVIndefiniteAnimatedView alloc] initWithFrame:CGRectZero];
|
|
_indefiniteAnimatedView.strokeThickness = SVProgressHUDRingThickness;
|
|
_indefiniteAnimatedView.strokeColor = self.is2 ? SVProgressHUDForegroundColor2 : SVProgressHUDForegroundColor ;
|
|
_indefiniteAnimatedView.radius = self.stringLabel.text ? SVProgressHUDRingRadius : SVProgressHUDRingNoTextRadius;
|
|
[_indefiniteAnimatedView sizeToFit];
|
|
}
|
|
return _indefiniteAnimatedView;
|
|
}
|
|
|
|
- (CAShapeLayer *)ringLayer {
|
|
if(!_ringLayer) {
|
|
CGPoint center = CGPointMake(CGRectGetWidth(_hudView.frame)/2, CGRectGetHeight(_hudView.frame)/2);
|
|
_ringLayer = [self createRingLayerWithCenter:center
|
|
radius:SVProgressHUDRingRadius
|
|
lineWidth:SVProgressHUDRingThickness
|
|
color:self.is2 ? SVProgressHUDForegroundColor2 : SVProgressHUDForegroundColor ];
|
|
[self.hudView.layer addSublayer:_ringLayer];
|
|
}
|
|
return _ringLayer;
|
|
}
|
|
|
|
- (CAShapeLayer *)backgroundRingLayer {
|
|
if(!_backgroundRingLayer) {
|
|
CGPoint center = CGPointMake(CGRectGetWidth(_hudView.frame)/2, CGRectGetHeight(_hudView.frame)/2);
|
|
_backgroundRingLayer = [self createRingLayerWithCenter:center
|
|
radius:SVProgressHUDRingRadius
|
|
lineWidth:SVProgressHUDRingThickness
|
|
color:[self.is2 ? SVProgressHUDForegroundColor2 : SVProgressHUDForegroundColor colorWithAlphaComponent:0.1f]];
|
|
_backgroundRingLayer.strokeEnd = 1;
|
|
[self.hudView.layer addSublayer:_backgroundRingLayer];
|
|
}
|
|
return _backgroundRingLayer;
|
|
}
|
|
|
|
- (void)cancelRingLayerAnimation {
|
|
[CATransaction begin];
|
|
[CATransaction setDisableActions:YES];
|
|
[_hudView.layer removeAllAnimations];
|
|
|
|
_ringLayer.strokeEnd = 0.0f;
|
|
if (_ringLayer.superlayer) {
|
|
[_ringLayer removeFromSuperlayer];
|
|
}
|
|
_ringLayer = nil;
|
|
|
|
if (_backgroundRingLayer.superlayer) {
|
|
[_backgroundRingLayer removeFromSuperlayer];
|
|
}
|
|
_backgroundRingLayer = nil;
|
|
|
|
[CATransaction commit];
|
|
}
|
|
|
|
- (CAShapeLayer *)createRingLayerWithCenter:(CGPoint)center radius:(CGFloat)radius lineWidth:(CGFloat)lineWidth color:(UIColor *)color {
|
|
|
|
UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(radius, radius) radius:radius startAngle:-M_PI_2 endAngle:(M_PI + M_PI_2) clockwise:YES];
|
|
|
|
CAShapeLayer *slice = [CAShapeLayer layer];
|
|
slice.contentsScale = [[UIScreen mainScreen] scale];
|
|
slice.frame = CGRectMake(center.x-radius, center.y-radius, radius*2, radius*2);
|
|
slice.fillColor = [UIColor clearColor].CGColor;
|
|
slice.strokeColor = color.CGColor;
|
|
slice.lineWidth = lineWidth;
|
|
slice.lineCap = kCALineCapRound;
|
|
slice.lineJoin = kCALineJoinBevel;
|
|
slice.path = smoothedPath.CGPath;
|
|
|
|
return slice;
|
|
}
|
|
|
|
#pragma mark - Utilities
|
|
|
|
+ (BOOL)isVisible {
|
|
return ([self sharedView].alpha == 1);
|
|
}
|
|
|
|
+ (BOOL)isVisible2 {
|
|
return ([self sharedView2].alpha == 1);
|
|
}
|
|
|
|
|
|
#pragma mark - Getters
|
|
|
|
- (NSTimeInterval)displayDurationForString:(NSString*)string {
|
|
return MIN((float)string.length*0.06 + 0.5, 5.0);
|
|
}
|
|
|
|
- (BOOL)isClear { // used for iOS 7 and above
|
|
return (self.maskType == SVProgressHUDMaskTypeClear || self.maskType == SVProgressHUDMaskTypeNone);
|
|
}
|
|
|
|
- (UIControl *)overlayView {
|
|
if(!_overlayView) {
|
|
_overlayView = [[UIControl alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
|
_overlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
_overlayView.backgroundColor = [UIColor clearColor];
|
|
[_overlayView addTarget:self action:@selector(overlayViewDidReceiveTouchEvent:forEvent:) forControlEvents:UIControlEventTouchDown];
|
|
}
|
|
return _overlayView;
|
|
}
|
|
|
|
- (UIView *)hudView {
|
|
if(!_hudView) {
|
|
_hudView = [[UIView alloc] initWithFrame:CGRectZero];
|
|
_hudView.backgroundColor = self.is2 ? SVProgressHUDBackgroundColor2 : SVProgressHUDBackgroundColor;
|
|
_hudView.layer.cornerRadius = 14;
|
|
_hudView.layer.masksToBounds = YES;
|
|
|
|
_hudView.autoresizingMask = (UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin |
|
|
UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin);
|
|
|
|
if ([_hudView respondsToSelector:@selector(addMotionEffect:)]) {
|
|
UIInterpolatingMotionEffect *effectX = [[UIInterpolatingMotionEffect alloc] initWithKeyPath: @"center.x" type: UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
|
|
effectX.minimumRelativeValue = @(-SVProgressHUDParallaxDepthPoints);
|
|
effectX.maximumRelativeValue = @(SVProgressHUDParallaxDepthPoints);
|
|
|
|
UIInterpolatingMotionEffect *effectY = [[UIInterpolatingMotionEffect alloc] initWithKeyPath: @"center.y" type: UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
|
|
effectY.minimumRelativeValue = @(-SVProgressHUDParallaxDepthPoints);
|
|
effectY.maximumRelativeValue = @(SVProgressHUDParallaxDepthPoints);
|
|
|
|
UIMotionEffectGroup *effectGroup = [[UIMotionEffectGroup alloc] init];
|
|
effectGroup.motionEffects = @[effectX, effectY];
|
|
[_hudView addMotionEffect:effectGroup];
|
|
}
|
|
}
|
|
|
|
if(!_hudView.superview)
|
|
[self addSubview:_hudView];
|
|
|
|
return _hudView;
|
|
}
|
|
|
|
- (UILabel *)stringLabel {
|
|
if (!_stringLabel) {
|
|
_stringLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
|
_stringLabel.backgroundColor = [UIColor clearColor];
|
|
_stringLabel.adjustsFontSizeToFitWidth = YES;
|
|
_stringLabel.textAlignment = NSTextAlignmentCenter;
|
|
_stringLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
|
|
_stringLabel.numberOfLines = 0;
|
|
}
|
|
|
|
if(!_stringLabel.superview)
|
|
[self.hudView addSubview:_stringLabel];
|
|
|
|
_stringLabel.textColor = self.is2 ? SVProgressHUDForegroundColor2 : SVProgressHUDForegroundColor;
|
|
_stringLabel.font = SVProgressHUDFont;
|
|
|
|
return _stringLabel;
|
|
}
|
|
|
|
- (UIImageView *)imageView {
|
|
if (!_imageView)
|
|
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 28.0f, 28.0f)];
|
|
|
|
if(!_imageView.superview)
|
|
[self.hudView addSubview:_imageView];
|
|
|
|
return _imageView;
|
|
}
|
|
|
|
|
|
- (CGFloat)visibleKeyboardHeight {
|
|
#if !defined(SV_APP_EXTENSIONS)
|
|
UIWindow *keyboardWindow = nil;
|
|
for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) {
|
|
if(![[testWindow class] isEqual:[UIWindow class]]) {
|
|
keyboardWindow = testWindow;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (__strong UIView *possibleKeyboard in [keyboardWindow subviews]) {
|
|
if ([possibleKeyboard isKindOfClass:NSClassFromString(@"UIPeripheralHostView")] || [possibleKeyboard isKindOfClass:NSClassFromString(@"UIKeyboard")]) {
|
|
return CGRectGetHeight(possibleKeyboard.bounds);
|
|
} else if ([possibleKeyboard isKindOfClass:NSClassFromString(@"UIInputSetContainerView")]) {
|
|
for (__strong UIView *possibleKeyboardSubview in [possibleKeyboard subviews]) {
|
|
if ([possibleKeyboardSubview isKindOfClass:NSClassFromString(@"UIInputSetHostView")]) {
|
|
return CGRectGetHeight(possibleKeyboardSubview.bounds);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
@end
|
|
|