| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485 | //// MBProgressHUD.m// Version 1.0.0// Created by Matej Bukovinski on 2.4.09.//#import "MBProgressHUD.h"#import <tgmath.h>#ifndef kCFCoreFoundationVersionNumber_iOS_7_0    #define kCFCoreFoundationVersionNumber_iOS_7_0 847.20#endif#ifndef kCFCoreFoundationVersionNumber_iOS_8_0    #define kCFCoreFoundationVersionNumber_iOS_8_0 1129.15#endif#define MBMainThreadAssert() NSAssert([NSThread isMainThread], @"MBProgressHUD needs to be accessed on the main thread.");CGFloat const MBProgressMaxOffset = 1000000.f;static const CGFloat MBDefaultPadding = 4.f;static const CGFloat MBDefaultLabelFontSize = 16.f;static const CGFloat MBDefaultDetailsLabelFontSize = 12.f;@interface MBProgressHUD () {    // Deprecated    UIColor *_activityIndicatorColor;    CGFloat _opacity;}@property (nonatomic, assign) BOOL useAnimation;@property (nonatomic, assign, getter=hasFinished) BOOL finished;@property (nonatomic, strong) UIView *indicator;@property (nonatomic, strong) NSDate *showStarted;@property (nonatomic, strong) NSArray *paddingConstraints;@property (nonatomic, strong) NSArray *bezelConstraints;@property (nonatomic, strong) UIView *topSpacer;@property (nonatomic, strong) UIView *bottomSpacer;@property (nonatomic, weak) NSTimer *graceTimer;@property (nonatomic, weak) NSTimer *minShowTimer;@property (nonatomic, weak) NSTimer *hideDelayTimer;@property (nonatomic, weak) CADisplayLink *progressObjectDisplayLink;// Deprecated@property (assign) BOOL taskInProgress;@end@interface MBProgressHUDRoundedButton : UIButton@end@implementation MBProgressHUD#pragma mark - Class methods+ (instancetype)showHUDAddedTo:(UIView *)view animated:(BOOL)animated {    MBProgressHUD *hud = [[self alloc] initWithView:view];    hud.removeFromSuperViewOnHide = YES;    [view addSubview:hud];    [hud showAnimated:animated];    return hud;}+ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated {    MBProgressHUD *hud = [self HUDForView:view];    if (hud != nil) {        hud.removeFromSuperViewOnHide = YES;        [hud hideAnimated:animated];        return YES;    }    return NO;}+ (MBProgressHUD *)HUDForView:(UIView *)view {    NSEnumerator *subviewsEnum = [view.subviews reverseObjectEnumerator];    for (UIView *subview in subviewsEnum) {        if ([subview isKindOfClass:self]) {            return (MBProgressHUD *)subview;        }    }    return nil;}#pragma mark - Lifecycle- (void)commonInit {    // Set default values for properties    _animationType = MBProgressHUDAnimationFade;    _mode = MBProgressHUDModeIndeterminate;    _margin = 20.0f;    _opacity = 1.f;    _defaultMotionEffectsEnabled = YES;    // Default color, depending on the current iOS version    BOOL isLegacy = kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0;    _contentColor = isLegacy ? [UIColor whiteColor] : [UIColor colorWithWhite:0.f alpha:0.7f];    // Transparent background    self.opaque = NO;    self.backgroundColor = [UIColor clearColor];    // Make it invisible for now    self.alpha = 0.0f;    self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;    self.layer.allowsGroupOpacity = NO;    [self setupViews];    [self updateIndicators];    [self registerForNotifications];}- (instancetype)initWithFrame:(CGRect)frame {    if ((self = [super initWithFrame:frame])) {        [self commonInit];    }    return self;}- (instancetype)initWithCoder:(NSCoder *)aDecoder {    if ((self = [super initWithCoder:aDecoder])) {        [self commonInit];    }    return self;}- (id)initWithView:(UIView *)view {    NSAssert(view, @"View must not be nil.");    return [self initWithFrame:view.bounds];}- (void)dealloc {    [self unregisterFromNotifications];}#pragma mark - Show & hide- (void)showAnimated:(BOOL)animated {    MBMainThreadAssert();    [self.minShowTimer invalidate];    self.useAnimation = animated;    self.finished = NO;    // If the grace time is set, postpone the HUD display    if (self.graceTime > 0.0) {        NSTimer *timer = [NSTimer timerWithTimeInterval:self.graceTime target:self selector:@selector(handleGraceTimer:) userInfo:nil repeats:NO];        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];        self.graceTimer = timer;    }     // ... otherwise show the HUD immediately    else {        [self showUsingAnimation:self.useAnimation];    }}- (void)hideAnimated:(BOOL)animated {    MBMainThreadAssert();    [self.graceTimer invalidate];    self.useAnimation = animated;    self.finished = YES;    // If the minShow time is set, calculate how long the HUD was shown,    // and postpone the hiding operation if necessary    if (self.minShowTime > 0.0 && self.showStarted) {        NSTimeInterval interv = [[NSDate date] timeIntervalSinceDate:self.showStarted];        if (interv < self.minShowTime) {            NSTimer *timer = [NSTimer timerWithTimeInterval:(self.minShowTime - interv) target:self selector:@selector(handleMinShowTimer:) userInfo:nil repeats:NO];            [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];            self.minShowTimer = timer;            return;        }     }    // ... otherwise hide the HUD immediately    [self hideUsingAnimation:self.useAnimation];}- (void)hideAnimated:(BOOL)animated afterDelay:(NSTimeInterval)delay {    NSTimer *timer = [NSTimer timerWithTimeInterval:delay target:self selector:@selector(handleHideTimer:) userInfo:@(animated) repeats:NO];    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];    self.hideDelayTimer = timer;}#pragma mark - Timer callbacks- (void)handleGraceTimer:(NSTimer *)theTimer {    // Show the HUD only if the task is still running    if (!self.hasFinished) {        [self showUsingAnimation:self.useAnimation];    }}- (void)handleMinShowTimer:(NSTimer *)theTimer {    [self hideUsingAnimation:self.useAnimation];}- (void)handleHideTimer:(NSTimer *)timer {    [self hideAnimated:[timer.userInfo boolValue]];}#pragma mark - View Hierrarchy- (void)didMoveToSuperview {    [self updateForCurrentOrientationAnimated:NO];}#pragma mark - Internal show & hide operations- (void)showUsingAnimation:(BOOL)animated {    // Cancel any previous animations    [self.bezelView.layer removeAllAnimations];    [self.backgroundView.layer removeAllAnimations];    // Cancel any scheduled hideDelayed: calls    [self.hideDelayTimer invalidate];    self.showStarted = [NSDate date];    self.alpha = 1.f;    // Needed in case we hide and re-show with the same NSProgress object attached.    [self setNSProgressDisplayLinkEnabled:YES];    if (animated) {        [self animateIn:YES withType:self.animationType completion:NULL];    } else {#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wdeprecated-declarations"        self.bezelView.alpha = self.opacity;#pragma clang diagnostic pop        self.backgroundView.alpha = 1.f;    }}- (void)hideUsingAnimation:(BOOL)animated {    if (animated && self.showStarted) {        self.showStarted = nil;        [self animateIn:NO withType:self.animationType completion:^(BOOL finished) {            [self done];        }];    } else {        self.showStarted = nil;        self.bezelView.alpha = 0.f;        self.backgroundView.alpha = 1.f;        [self done];    }}- (void)animateIn:(BOOL)animatingIn withType:(MBProgressHUDAnimation)type completion:(void(^)(BOOL finished))completion {    // Automatically determine the correct zoom animation type    if (type == MBProgressHUDAnimationZoom) {        type = animatingIn ? MBProgressHUDAnimationZoomIn : MBProgressHUDAnimationZoomOut;    }    CGAffineTransform small = CGAffineTransformMakeScale(0.5f, 0.5f);    CGAffineTransform large = CGAffineTransformMakeScale(1.5f, 1.5f);    // Set starting state    UIView *bezelView = self.bezelView;    if (animatingIn && bezelView.alpha == 0.f && type == MBProgressHUDAnimationZoomIn) {        bezelView.transform = small;    } else if (animatingIn && bezelView.alpha == 0.f && type == MBProgressHUDAnimationZoomOut) {        bezelView.transform = large;    }    // Perform animations    dispatch_block_t animations = ^{        if (animatingIn) {            bezelView.transform = CGAffineTransformIdentity;        } else if (!animatingIn && type == MBProgressHUDAnimationZoomIn) {            bezelView.transform = large;        } else if (!animatingIn && type == MBProgressHUDAnimationZoomOut) {            bezelView.transform = small;        }#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wdeprecated-declarations"        bezelView.alpha = animatingIn ? self.opacity : 0.f;#pragma clang diagnostic pop        self.backgroundView.alpha = animatingIn ? 1.f : 0.f;    };    // Spring animations are nicer, but only available on iOS 7+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 || TARGET_OS_TV    if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_7_0) {        [UIView animateWithDuration:0.3 delay:0. usingSpringWithDamping:1.f initialSpringVelocity:0.f options:UIViewAnimationOptionBeginFromCurrentState animations:animations completion:completion];        return;    }#endif    [UIView animateWithDuration:0.3 delay:0. options:UIViewAnimationOptionBeginFromCurrentState animations:animations completion:completion];}- (void)done {    // Cancel any scheduled hideDelayed: calls    [self.hideDelayTimer invalidate];    [self setNSProgressDisplayLinkEnabled:NO];    if (self.hasFinished) {        self.alpha = 0.0f;        if (self.removeFromSuperViewOnHide) {            [self removeFromSuperview];        }    }    MBProgressHUDCompletionBlock completionBlock = self.completionBlock;    if (completionBlock) {        completionBlock();    }    id<MBProgressHUDDelegate> delegate = self.delegate;    if ([delegate respondsToSelector:@selector(hudWasHidden:)]) {        [delegate performSelector:@selector(hudWasHidden:) withObject:self];    }}#pragma mark - UI- (void)setupViews {    UIColor *defaultColor = self.contentColor;    MBBackgroundView *backgroundView = [[MBBackgroundView alloc] initWithFrame:self.bounds];    backgroundView.style = MBProgressHUDBackgroundStyleSolidColor;    backgroundView.backgroundColor = [UIColor clearColor];    backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;    backgroundView.alpha = 0.f;    [self addSubview:backgroundView];    _backgroundView = backgroundView;    MBBackgroundView *bezelView = [MBBackgroundView new];    bezelView.translatesAutoresizingMaskIntoConstraints = NO;    bezelView.layer.cornerRadius = 5.f;    bezelView.alpha = 0.f;    [self addSubview:bezelView];    _bezelView = bezelView;    [self updateBezelMotionEffects];    UILabel *label = [UILabel new];    label.adjustsFontSizeToFitWidth = NO;    label.textAlignment = NSTextAlignmentCenter;    label.textColor = defaultColor;    label.font = [UIFont boldSystemFontOfSize:MBDefaultLabelFontSize];    label.opaque = NO;    label.backgroundColor = [UIColor clearColor];    _label = label;    UILabel *detailsLabel = [UILabel new];    detailsLabel.adjustsFontSizeToFitWidth = NO;    detailsLabel.textAlignment = NSTextAlignmentCenter;    detailsLabel.textColor = defaultColor;    detailsLabel.numberOfLines = 0;    detailsLabel.font = [UIFont boldSystemFontOfSize:MBDefaultDetailsLabelFontSize];    detailsLabel.opaque = NO;    detailsLabel.backgroundColor = [UIColor clearColor];    _detailsLabel = detailsLabel;    UIButton *button = [MBProgressHUDRoundedButton buttonWithType:UIButtonTypeCustom];    button.titleLabel.textAlignment = NSTextAlignmentCenter;    button.titleLabel.font = [UIFont boldSystemFontOfSize:MBDefaultDetailsLabelFontSize];    [button setTitleColor:defaultColor forState:UIControlStateNormal];    _button = button;    for (UIView *view in @[label, detailsLabel, button]) {        view.translatesAutoresizingMaskIntoConstraints = NO;        [view setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisHorizontal];        [view setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisVertical];        [bezelView addSubview:view];    }    UIView *topSpacer = [UIView new];    topSpacer.translatesAutoresizingMaskIntoConstraints = NO;    topSpacer.hidden = YES;    [bezelView addSubview:topSpacer];    _topSpacer = topSpacer;    UIView *bottomSpacer = [UIView new];    bottomSpacer.translatesAutoresizingMaskIntoConstraints = NO;    bottomSpacer.hidden = YES;    [bezelView addSubview:bottomSpacer];    _bottomSpacer = bottomSpacer;}- (void)updateIndicators {    UIView *indicator = self.indicator;    BOOL isActivityIndicator = [indicator isKindOfClass:[UIActivityIndicatorView class]];    BOOL isRoundIndicator = [indicator isKindOfClass:[MBRoundProgressView class]];    MBProgressHUDMode mode = self.mode;    if (mode == MBProgressHUDModeIndeterminate) {        if (!isActivityIndicator) {            // Update to indeterminate indicator            [indicator removeFromSuperview];            indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];            [(UIActivityIndicatorView *)indicator startAnimating];            [self.bezelView addSubview:indicator];        }    }    else if (mode == MBProgressHUDModeDeterminateHorizontalBar) {        // Update to bar determinate indicator        [indicator removeFromSuperview];        indicator = [[MBBarProgressView alloc] init];        [self.bezelView addSubview:indicator];    }    else if (mode == MBProgressHUDModeDeterminate || mode == MBProgressHUDModeAnnularDeterminate) {        if (!isRoundIndicator) {            // Update to determinante indicator            [indicator removeFromSuperview];            indicator = [[MBRoundProgressView alloc] init];            [self.bezelView addSubview:indicator];        }        if (mode == MBProgressHUDModeAnnularDeterminate) {            [(MBRoundProgressView *)indicator setAnnular:YES];        }    }     else if (mode == MBProgressHUDModeCustomView && self.customView != indicator) {        // Update custom view indicator        [indicator removeFromSuperview];        indicator = self.customView;        [self.bezelView addSubview:indicator];    }    else if (mode == MBProgressHUDModeText) {        [indicator removeFromSuperview];        indicator = nil;    }    indicator.translatesAutoresizingMaskIntoConstraints = NO;    self.indicator = indicator;    if ([indicator respondsToSelector:@selector(setProgress:)]) {        [(id)indicator setValue:@(self.progress) forKey:@"progress"];    }    [indicator setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisHorizontal];    [indicator setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisVertical];    [self updateViewsForColor:self.contentColor];    [self setNeedsUpdateConstraints];}- (void)updateViewsForColor:(UIColor *)color {    if (!color) return;    self.label.textColor = color;    self.detailsLabel.textColor = color;    [self.button setTitleColor:color forState:UIControlStateNormal];#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wdeprecated-declarations"    if (self.activityIndicatorColor) {        color = self.activityIndicatorColor;    }#pragma clang diagnostic pop    // UIAppearance settings are prioritized. If they are preset the set color is ignored.    UIView *indicator = self.indicator;    if ([indicator isKindOfClass:[UIActivityIndicatorView class]]) {        UIActivityIndicatorView *appearance = nil;#if __IPHONE_OS_VERSION_MIN_REQUIRED < 90000        appearance = [UIActivityIndicatorView appearanceWhenContainedIn:[MBProgressHUD class], nil];#else        // For iOS 9+        appearance = [UIActivityIndicatorView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]];#endif                if (appearance.color == nil) {            ((UIActivityIndicatorView *)indicator).color = color;        }    } else if ([indicator isKindOfClass:[MBRoundProgressView class]]) {        MBRoundProgressView *appearance = nil;#if __IPHONE_OS_VERSION_MIN_REQUIRED < 90000        appearance = [MBRoundProgressView appearanceWhenContainedIn:[MBProgressHUD class], nil];#else        appearance = [MBRoundProgressView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]];#endif        if (appearance.progressTintColor == nil) {            ((MBRoundProgressView *)indicator).progressTintColor = color;        }        if (appearance.backgroundTintColor == nil) {            ((MBRoundProgressView *)indicator).backgroundTintColor = [UIColor clearColor];        }    } else if ([indicator isKindOfClass:[MBBarProgressView class]]) {        MBBarProgressView *appearance = nil;#if __IPHONE_OS_VERSION_MIN_REQUIRED < 90000        appearance = [MBBarProgressView appearanceWhenContainedIn:[MBProgressHUD class], nil];#else        appearance = [MBBarProgressView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]];#endif        if (appearance.progressColor == nil) {            ((MBBarProgressView *)indicator).progressColor = color;        }        if (appearance.lineColor == nil) {            ((MBBarProgressView *)indicator).lineColor = color;        }    } else {#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 || TARGET_OS_TV        if ([indicator respondsToSelector:@selector(setTintColor:)]) {            [indicator setTintColor:color];        }#endif    }}- (void)updateBezelMotionEffects {#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 || TARGET_OS_TV    MBBackgroundView *bezelView = self.bezelView;    if (![bezelView respondsToSelector:@selector(addMotionEffect:)]) return;    if (self.defaultMotionEffectsEnabled) {        CGFloat effectOffset = 10.f;        UIInterpolatingMotionEffect *effectX = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];        effectX.maximumRelativeValue = @(effectOffset);        effectX.minimumRelativeValue = @(-effectOffset);        UIInterpolatingMotionEffect *effectY = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];        effectY.maximumRelativeValue = @(effectOffset);        effectY.minimumRelativeValue = @(-effectOffset);        UIMotionEffectGroup *group = [[UIMotionEffectGroup alloc] init];        group.motionEffects = @[effectX, effectY];        [bezelView addMotionEffect:group];    } else {        NSArray *effects = [bezelView motionEffects];        for (UIMotionEffect *effect in effects) {            [bezelView removeMotionEffect:effect];        }    }#endif}#pragma mark - Layout- (void)updateConstraints {    UIView *bezel = self.bezelView;    UIView *topSpacer = self.topSpacer;    UIView *bottomSpacer = self.bottomSpacer;    CGFloat margin = self.margin;    NSMutableArray *bezelConstraints = [NSMutableArray array];    NSDictionary *metrics = @{@"margin": @(margin)};    NSMutableArray *subviews = [NSMutableArray arrayWithObjects:self.topSpacer, self.label, self.detailsLabel, self.button, self.bottomSpacer, nil];    if (self.indicator) [subviews insertObject:self.indicator atIndex:1];    // Remove existing constraints    [self removeConstraints:self.constraints];    [topSpacer removeConstraints:topSpacer.constraints];    [bottomSpacer removeConstraints:bottomSpacer.constraints];    if (self.bezelConstraints) {        [bezel removeConstraints:self.bezelConstraints];        self.bezelConstraints = nil;    }    // Center bezel in container (self), applying the offset if set    CGPoint offset = self.offset;    NSMutableArray *centeringConstraints = [NSMutableArray array];    [centeringConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.f constant:offset.x]];    [centeringConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.f constant:offset.y]];    [self applyPriority:998.f toConstraints:centeringConstraints];    [self addConstraints:centeringConstraints];    // Ensure minimum side margin is kept    NSMutableArray *sideConstraints = [NSMutableArray array];    [sideConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>=margin)-[bezel]-(>=margin)-|" options:0 metrics:metrics views:NSDictionaryOfVariableBindings(bezel)]];    [sideConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(>=margin)-[bezel]-(>=margin)-|" options:0 metrics:metrics views:NSDictionaryOfVariableBindings(bezel)]];    [self applyPriority:999.f toConstraints:sideConstraints];    [self addConstraints:sideConstraints];    // Minimum bezel size, if set    CGSize minimumSize = self.minSize;    if (!CGSizeEqualToSize(minimumSize, CGSizeZero)) {        NSMutableArray *minSizeConstraints = [NSMutableArray array];        [minSizeConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:minimumSize.width]];        [minSizeConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:minimumSize.height]];        [self applyPriority:997.f toConstraints:minSizeConstraints];        [bezelConstraints addObjectsFromArray:minSizeConstraints];    }    // Square aspect ratio, if set    if (self.square) {        NSLayoutConstraint *square = [NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeWidth multiplier:1.f constant:0];        square.priority = 997.f;        [bezelConstraints addObject:square];    }    // Top and bottom spacing    [topSpacer addConstraint:[NSLayoutConstraint constraintWithItem:topSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:margin]];    [bottomSpacer addConstraint:[NSLayoutConstraint constraintWithItem:bottomSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:margin]];    // Top and bottom spaces should be equal    [bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:topSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:bottomSpacer attribute:NSLayoutAttributeHeight multiplier:1.f constant:0.f]];    // Layout subviews in bezel    NSMutableArray *paddingConstraints = [NSMutableArray new];    [subviews enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop) {        // Center in bezel        [bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeCenterX multiplier:1.f constant:0.f]];        // Ensure the minimum edge margin is kept        [bezelConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>=margin)-[view]-(>=margin)-|" options:0 metrics:metrics views:NSDictionaryOfVariableBindings(view)]];        // Element spacing        if (idx == 0) {            // First, ensure spacing to bezel edge            [bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeTop multiplier:1.f constant:0.f]];        } else if (idx == subviews.count - 1) {            // Last, ensure spacing to bezel edge            [bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]];        }        if (idx > 0) {            // Has previous            NSLayoutConstraint *padding = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:subviews[idx - 1] attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f];            [bezelConstraints addObject:padding];            [paddingConstraints addObject:padding];        }    }];    [bezel addConstraints:bezelConstraints];    self.bezelConstraints = bezelConstraints;        self.paddingConstraints = [paddingConstraints copy];    [self updatePaddingConstraints];        [super updateConstraints];}- (void)layoutSubviews {    // There is no need to update constraints if they are going to    // be recreated in [super layoutSubviews] due to needsUpdateConstraints being set.    // This also avoids an issue on iOS 8, where updatePaddingConstraints    // would trigger a zombie object access.    if (!self.needsUpdateConstraints) {        [self updatePaddingConstraints];    }    [super layoutSubviews];}- (void)updatePaddingConstraints {    // Set padding dynamically, depending on whether the view is visible or not    __block BOOL hasVisibleAncestors = NO;    [self.paddingConstraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *padding, NSUInteger idx, BOOL *stop) {        UIView *firstView = (UIView *)padding.firstItem;        UIView *secondView = (UIView *)padding.secondItem;        BOOL firstVisible = !firstView.hidden && !CGSizeEqualToSize(firstView.intrinsicContentSize, CGSizeZero);        BOOL secondVisible = !secondView.hidden && !CGSizeEqualToSize(secondView.intrinsicContentSize, CGSizeZero);        // Set if both views are visible or if there's a visible view on top that doesn't have padding        // added relative to the current view yet        padding.constant = (firstVisible && (secondVisible || hasVisibleAncestors)) ? MBDefaultPadding : 0.f;        hasVisibleAncestors |= secondVisible;    }];}- (void)applyPriority:(UILayoutPriority)priority toConstraints:(NSArray *)constraints {    for (NSLayoutConstraint *constraint in constraints) {        constraint.priority = priority;    }}#pragma mark - Properties- (void)setMode:(MBProgressHUDMode)mode {    if (mode != _mode) {        _mode = mode;        [self updateIndicators];    }}- (void)setCustomView:(UIView *)customView {    if (customView != _customView) {        _customView = customView;        if (self.mode == MBProgressHUDModeCustomView) {            [self updateIndicators];        }    }}- (void)setOffset:(CGPoint)offset {    if (!CGPointEqualToPoint(offset, _offset)) {        _offset = offset;        [self setNeedsUpdateConstraints];    }}- (void)setMargin:(CGFloat)margin {    if (margin != _margin) {        _margin = margin;        [self setNeedsUpdateConstraints];    }}- (void)setMinSize:(CGSize)minSize {    if (!CGSizeEqualToSize(minSize, _minSize)) {        _minSize = minSize;        [self setNeedsUpdateConstraints];    }}- (void)setSquare:(BOOL)square {    if (square != _square) {        _square = square;        [self setNeedsUpdateConstraints];    }}- (void)setProgressObjectDisplayLink:(CADisplayLink *)progressObjectDisplayLink {    if (progressObjectDisplayLink != _progressObjectDisplayLink) {        [_progressObjectDisplayLink invalidate];                _progressObjectDisplayLink = progressObjectDisplayLink;                [_progressObjectDisplayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];    }}- (void)setProgressObject:(NSProgress *)progressObject {    if (progressObject != _progressObject) {        _progressObject = progressObject;        [self setNSProgressDisplayLinkEnabled:YES];    }}- (void)setProgress:(float)progress {    if (progress != _progress) {        _progress = progress;        UIView *indicator = self.indicator;        if ([indicator respondsToSelector:@selector(setProgress:)]) {            [(id)indicator setValue:@(self.progress) forKey:@"progress"];        }    }}- (void)setContentColor:(UIColor *)contentColor {    if (contentColor != _contentColor && ![contentColor isEqual:_contentColor]) {        _contentColor = contentColor;        [self updateViewsForColor:contentColor];    }}- (void)setDefaultMotionEffectsEnabled:(BOOL)defaultMotionEffectsEnabled {    if (defaultMotionEffectsEnabled != _defaultMotionEffectsEnabled) {        _defaultMotionEffectsEnabled = defaultMotionEffectsEnabled;        [self updateBezelMotionEffects];    }}#pragma mark - NSProgress- (void)setNSProgressDisplayLinkEnabled:(BOOL)enabled {    // We're using CADisplayLink, because NSProgress can change very quickly and observing it may starve the main thread,    // so we're refreshing the progress only every frame draw    if (enabled && self.progressObject) {        // Only create if not already active.        if (!self.progressObjectDisplayLink) {            self.progressObjectDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateProgressFromProgressObject)];        }    } else {        self.progressObjectDisplayLink = nil;    }}- (void)updateProgressFromProgressObject {    self.progress = self.progressObject.fractionCompleted;}#pragma mark - Notifications- (void)registerForNotifications {#if !TARGET_OS_TV    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];    [nc addObserver:self selector:@selector(statusBarOrientationDidChange:)               name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];#endif}- (void)unregisterFromNotifications {#if !TARGET_OS_TV    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];    [nc removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];#endif}#if !TARGET_OS_TV- (void)statusBarOrientationDidChange:(NSNotification *)notification {    UIView *superview = self.superview;    if (!superview) {        return;    } else {        [self updateForCurrentOrientationAnimated:YES];    }}#endif- (void)updateForCurrentOrientationAnimated:(BOOL)animated {    // Stay in sync with the superview in any case    if (self.superview) {        self.bounds = self.superview.bounds;    }    // Not needed on iOS 8+, compile out when the deployment target allows,    // to avoid sharedApplication problems on extension targets#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000    // Only needed pre iOS 8 when added to a window    BOOL iOS8OrLater = kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0;    if (iOS8OrLater || ![self.superview isKindOfClass:[UIWindow class]]) return;    // Make extension friendly. Will not get called on extensions (iOS 8+) due to the above check.    // This just ensures we don't get a warning about extension-unsafe API.    Class UIApplicationClass = NSClassFromString(@"UIApplication");    if (!UIApplicationClass || ![UIApplicationClass respondsToSelector:@selector(sharedApplication)]) return;    UIApplication *application = [UIApplication performSelector:@selector(sharedApplication)];    UIInterfaceOrientation orientation = application.statusBarOrientation;    CGFloat radians = 0;        if (UIInterfaceOrientationIsLandscape(orientation)) {        radians = orientation == UIInterfaceOrientationLandscapeLeft ? -(CGFloat)M_PI_2 : (CGFloat)M_PI_2;        // Window coordinates differ!        self.bounds = CGRectMake(0, 0, self.bounds.size.height, self.bounds.size.width);    } else {        radians = orientation == UIInterfaceOrientationPortraitUpsideDown ? (CGFloat)M_PI : 0.f;    }    if (animated) {        [UIView animateWithDuration:0.3 animations:^{            self.transform = CGAffineTransformMakeRotation(radians);        }];    } else {        self.transform = CGAffineTransformMakeRotation(radians);    }#endif}@end@implementation MBRoundProgressView#pragma mark - Lifecycle- (id)init {    return [self initWithFrame:CGRectMake(0.f, 0.f, 37.f, 37.f)];}- (id)initWithFrame:(CGRect)frame {    self = [super initWithFrame:frame];    if (self) {        self.backgroundColor = [UIColor clearColor];        self.opaque = NO;        _progress = 0.f;        _annular = NO;        _progressTintColor = [[UIColor alloc] initWithWhite:1.f alpha:1.f];        //_backgroundTintColor = [[UIColor alloc] initWithWhite:1.f alpha:.1f];        _backgroundTintColor = [UIColor redColor];    }    return self;}#pragma mark - Layout- (CGSize)intrinsicContentSize {    return CGSizeMake(37.f, 37.f);}#pragma mark - Properties- (void)setProgress:(float)progress {    if (progress != _progress) {        _progress = progress;        [self setNeedsDisplay];    }}- (void)setProgressTintColor:(UIColor *)progressTintColor {    NSAssert(progressTintColor, @"The color should not be nil.");    if (progressTintColor != _progressTintColor && ![progressTintColor isEqual:_progressTintColor]) {        _progressTintColor = progressTintColor;        [self setNeedsDisplay];    }}- (void)setBackgroundTintColor:(UIColor *)backgroundTintColor {    NSAssert(backgroundTintColor, @"The color should not be nil.");    if (backgroundTintColor != _backgroundTintColor && ![backgroundTintColor isEqual:_backgroundTintColor]) {        _backgroundTintColor = [UIColor clearColor];        [self setNeedsDisplay];    }}#pragma mark - Drawing- (void)drawRect:(CGRect)rect {    CGContextRef context = UIGraphicsGetCurrentContext();    BOOL isPreiOS7 = kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0;    if (_annular) {        // Draw background        CGFloat lineWidth = isPreiOS7 ? 5.f : 2.f;        UIBezierPath *processBackgroundPath = [UIBezierPath bezierPath];        processBackgroundPath.lineWidth = lineWidth;        processBackgroundPath.lineCapStyle = kCGLineCapButt;        CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));        CGFloat radius = (self.bounds.size.width - lineWidth)/2;        CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees        CGFloat endAngle = (2 * (float)M_PI) + startAngle;        [processBackgroundPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];        [_backgroundTintColor set];        [processBackgroundPath stroke];        // Draw progress        UIBezierPath *processPath = [UIBezierPath bezierPath];        processPath.lineCapStyle = isPreiOS7 ? kCGLineCapRound : kCGLineCapSquare;        processPath.lineWidth = lineWidth;        endAngle = (self.progress * 2 * (float)M_PI) + startAngle;        [processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];        [_progressTintColor set];        [processPath stroke];    } else {        // Draw background        CGFloat lineWidth = 2.f;        CGRect allRect = self.bounds;        CGRect circleRect = CGRectInset(allRect, lineWidth/2.f, lineWidth/2.f);        CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));        [_progressTintColor setStroke];        [_backgroundTintColor setFill];        CGContextSetLineWidth(context, lineWidth);        if (isPreiOS7) {            CGContextFillEllipseInRect(context, circleRect);        }        CGContextStrokeEllipseInRect(context, circleRect);        // 90 degrees        CGFloat startAngle = - ((float)M_PI / 2.f);        // Draw progress        if (isPreiOS7) {            CGFloat radius = (CGRectGetWidth(self.bounds) / 2.f) - lineWidth;            CGFloat endAngle = (self.progress * 2.f * (float)M_PI) + startAngle;            [_progressTintColor setFill];            CGContextMoveToPoint(context, center.x, center.y);            CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0);            CGContextClosePath(context);            CGContextFillPath(context);        } else {            UIBezierPath *processPath = [UIBezierPath bezierPath];            processPath.lineCapStyle = kCGLineCapButt;            processPath.lineWidth = lineWidth * 2.f;            CGFloat radius = (CGRectGetWidth(self.bounds) / 2.f) - (processPath.lineWidth / 2.f);            CGFloat endAngle = (self.progress * 2.f * (float)M_PI) + startAngle;            [processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];            // Ensure that we don't get color overlaping when _progressTintColor alpha < 1.f.            CGContextSetBlendMode(context, kCGBlendModeCopy);            [_progressTintColor set];            [processPath stroke];        }    }}@end@implementation MBBarProgressView#pragma mark - Lifecycle- (id)init {    return [self initWithFrame:CGRectMake(.0f, .0f, 120.0f, 20.0f)];}- (id)initWithFrame:(CGRect)frame {    self = [super initWithFrame:frame];    if (self) {        _progress = 0.f;        _lineColor = [UIColor whiteColor];        _progressColor = [UIColor whiteColor];        _progressRemainingColor = [UIColor clearColor];        self.backgroundColor = [UIColor clearColor];        self.opaque = NO;    }    return self;}#pragma mark - Layout- (CGSize)intrinsicContentSize {    BOOL isPreiOS7 = kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0;    return CGSizeMake(120.f, isPreiOS7 ? 20.f : 10.f);}#pragma mark - Properties- (void)setProgress:(float)progress {    if (progress != _progress) {        _progress = progress;        [self setNeedsDisplay];    }}- (void)setProgressColor:(UIColor *)progressColor {    NSAssert(progressColor, @"The color should not be nil.");    if (progressColor != _progressColor && ![progressColor isEqual:_progressColor]) {        _progressColor = progressColor;        [self setNeedsDisplay];    }}- (void)setProgressRemainingColor:(UIColor *)progressRemainingColor {    NSAssert(progressRemainingColor, @"The color should not be nil.");    if (progressRemainingColor != _progressRemainingColor && ![progressRemainingColor isEqual:_progressRemainingColor]) {        _progressRemainingColor = progressRemainingColor;        [self setNeedsDisplay];    }}#pragma mark - Drawing- (void)drawRect:(CGRect)rect {    CGContextRef context = UIGraphicsGetCurrentContext();        CGContextSetLineWidth(context, 2);    CGContextSetStrokeColorWithColor(context,[_lineColor CGColor]);    CGContextSetFillColorWithColor(context, [_progressRemainingColor CGColor]);        // Draw background    CGFloat radius = (rect.size.height / 2) - 2;    CGContextMoveToPoint(context, 2, rect.size.height/2);    CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius);    CGContextAddLineToPoint(context, rect.size.width - radius - 2, 2);    CGContextAddArcToPoint(context, rect.size.width - 2, 2, rect.size.width - 2, rect.size.height / 2, radius);    CGContextAddArcToPoint(context, rect.size.width - 2, rect.size.height - 2, rect.size.width - radius - 2, rect.size.height - 2, radius);    CGContextAddLineToPoint(context, radius + 2, rect.size.height - 2);    CGContextAddArcToPoint(context, 2, rect.size.height - 2, 2, rect.size.height/2, radius);    CGContextFillPath(context);        // Draw border    CGContextMoveToPoint(context, 2, rect.size.height/2);    CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius);    CGContextAddLineToPoint(context, rect.size.width - radius - 2, 2);    CGContextAddArcToPoint(context, rect.size.width - 2, 2, rect.size.width - 2, rect.size.height / 2, radius);    CGContextAddArcToPoint(context, rect.size.width - 2, rect.size.height - 2, rect.size.width - radius - 2, rect.size.height - 2, radius);    CGContextAddLineToPoint(context, radius + 2, rect.size.height - 2);    CGContextAddArcToPoint(context, 2, rect.size.height - 2, 2, rect.size.height/2, radius);    CGContextStrokePath(context);        CGContextSetFillColorWithColor(context, [_progressColor CGColor]);    radius = radius - 2;    CGFloat amount = self.progress * rect.size.width;        // Progress in the middle area    if (amount >= radius + 4 && amount <= (rect.size.width - radius - 4)) {        CGContextMoveToPoint(context, 4, rect.size.height/2);        CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);        CGContextAddLineToPoint(context, amount, 4);        CGContextAddLineToPoint(context, amount, radius + 4);                CGContextMoveToPoint(context, 4, rect.size.height/2);        CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius);        CGContextAddLineToPoint(context, amount, rect.size.height - 4);        CGContextAddLineToPoint(context, amount, radius + 4);                CGContextFillPath(context);    }        // Progress in the right arc    else if (amount > radius + 4) {        CGFloat x = amount - (rect.size.width - radius - 4);        CGContextMoveToPoint(context, 4, rect.size.height/2);        CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);        CGContextAddLineToPoint(context, rect.size.width - radius - 4, 4);        CGFloat angle = -acos(x/radius);        if (isnan(angle)) angle = 0;        CGContextAddArc(context, rect.size.width - radius - 4, rect.size.height/2, radius, M_PI, angle, 0);        CGContextAddLineToPoint(context, amount, rect.size.height/2);        CGContextMoveToPoint(context, 4, rect.size.height/2);        CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius);        CGContextAddLineToPoint(context, rect.size.width - radius - 4, rect.size.height - 4);        angle = acos(x/radius);        if (isnan(angle)) angle = 0;        CGContextAddArc(context, rect.size.width - radius - 4, rect.size.height/2, radius, -M_PI, angle, 1);        CGContextAddLineToPoint(context, amount, rect.size.height/2);                CGContextFillPath(context);    }        // Progress is in the left arc    else if (amount < radius + 4 && amount > 0) {        CGContextMoveToPoint(context, 4, rect.size.height/2);        CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);        CGContextAddLineToPoint(context, radius + 4, rect.size.height/2);        CGContextMoveToPoint(context, 4, rect.size.height/2);        CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius);        CGContextAddLineToPoint(context, radius + 4, rect.size.height/2);                CGContextFillPath(context);    }}@end@interface MBBackgroundView ()#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV@property UIVisualEffectView *effectView;#endif#if !TARGET_OS_TV@property UIToolbar *toolbar;#endif@end@implementation MBBackgroundView#pragma mark - Lifecycle- (instancetype)initWithFrame:(CGRect)frame {    if ((self = [super initWithFrame:frame])) {        if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_7_0) {            _style = MBProgressHUDBackgroundStyleBlur;            if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {                _color = [UIColor colorWithWhite:0.8f alpha:0.6f];            } else {                _color = [UIColor colorWithWhite:0.95f alpha:0.6f];            }        } else {            _style = MBProgressHUDBackgroundStyleSolidColor;            _color = [[UIColor blackColor] colorWithAlphaComponent:0.8];        }        self.clipsToBounds = YES;        [self updateForBackgroundStyle];    }    return self;}#pragma mark - Layout- (CGSize)intrinsicContentSize {    // Smallest size possible. Content pushes against this.    return CGSizeZero;}#pragma mark - Appearance- (void)setStyle:(MBProgressHUDBackgroundStyle)style {    if (style == MBProgressHUDBackgroundStyleBlur && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0) {        style = MBProgressHUDBackgroundStyleSolidColor;    }    if (_style != style) {        _style = style;        [self updateForBackgroundStyle];    }}- (void)setColor:(UIColor *)color {    NSAssert(color, @"The color should not be nil.");    if (color != _color && ![color isEqual:_color]) {        _color = color;        [self updateViewsForColor:color];    }}///////////////////////////////////////////////////////////////////////////////////////////#pragma mark - Views- (void)updateForBackgroundStyle {    MBProgressHUDBackgroundStyle style = self.style;    if (style == MBProgressHUDBackgroundStyleBlur) {#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV        if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {            UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];            UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect];            [self addSubview:effectView];            effectView.frame = self.bounds;            effectView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;            self.backgroundColor = self.color;            self.layer.allowsGroupOpacity = NO;            self.effectView = effectView;        } else {#endif#if !TARGET_OS_TV            UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectInset(self.bounds, -100.f, -100.f)];            toolbar.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;            toolbar.barTintColor = self.color;            toolbar.translucent = YES;            [self addSubview:toolbar];            self.toolbar = toolbar;#endif#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV        }#endif    } else {#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV        if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {            [self.effectView removeFromSuperview];            self.effectView = nil;        } else {#endif#if !TARGET_OS_TV            [self.toolbar removeFromSuperview];            self.toolbar = nil;#endif#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV        }#endif        self.backgroundColor = self.color;    }}- (void)updateViewsForColor:(UIColor *)color {    if (self.style == MBProgressHUDBackgroundStyleBlur) {        if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {            self.backgroundColor = self.color;        } else {#if !TARGET_OS_TV            self.toolbar.barTintColor = color;#endif        }    } else {        self.backgroundColor = self.color;    }}@end@implementation MBProgressHUD (Deprecated)#pragma mark - Class+ (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated {    NSArray *huds = [MBProgressHUD allHUDsForView:view];    for (MBProgressHUD *hud in huds) {        hud.removeFromSuperViewOnHide = YES;        [hud hideAnimated:animated];    }    return [huds count];}+ (NSArray *)allHUDsForView:(UIView *)view {    NSMutableArray *huds = [NSMutableArray array];    NSArray *subviews = view.subviews;    for (UIView *aView in subviews) {        if ([aView isKindOfClass:self]) {            [huds addObject:aView];        }    }    return [NSArray arrayWithArray:huds];}#pragma mark - Lifecycle- (id)initWithWindow:(UIWindow *)window {    return [self initWithView:window];}#pragma mark - Show & hide- (void)show:(BOOL)animated {    [self showAnimated:animated];}- (void)hide:(BOOL)animated {    [self hideAnimated:animated];}- (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay {    [self hideAnimated:animated afterDelay:delay];}#pragma mark - Threading- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated {    [self showAnimated:animated whileExecutingBlock:^{#pragma clang diagnostic push#pragma clang diagnostic ignored "-Warc-performSelector-leaks"        // Start executing the requested task        [target performSelector:method withObject:object];#pragma clang diagnostic pop    }];}- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block {    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    [self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:NULL];}- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(void (^)())completion {    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    [self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:completion];}- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue {    [self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:NULL];}- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue completionBlock:(nullable MBProgressHUDCompletionBlock)completion {    self.taskInProgress = YES;    self.completionBlock = completion;    dispatch_async(queue, ^(void) {        block();        dispatch_async(dispatch_get_main_queue(), ^(void) {            [self cleanUp];        });    });    [self showAnimated:animated];}- (void)cleanUp {    self.taskInProgress = NO;    [self hideAnimated:self.useAnimation];}#pragma mark - Labels- (NSString *)labelText {    return self.label.text;}- (void)setLabelText:(NSString *)labelText {    MBMainThreadAssert();    self.label.text = labelText;}- (UIFont *)labelFont {    return self.label.font;}- (void)setLabelFont:(UIFont *)labelFont {    MBMainThreadAssert();    self.label.font = labelFont;}- (UIColor *)labelColor {    return self.label.textColor;}- (void)setLabelColor:(UIColor *)labelColor {    MBMainThreadAssert();    self.label.textColor = labelColor;}- (NSString *)detailsLabelText {    return self.detailsLabel.text;}- (void)setDetailsLabelText:(NSString *)detailsLabelText {    MBMainThreadAssert();    self.detailsLabel.text = detailsLabelText;}- (UIFont *)detailsLabelFont {    return self.detailsLabel.font;}- (void)setDetailsLabelFont:(UIFont *)detailsLabelFont {    MBMainThreadAssert();    self.detailsLabel.font = detailsLabelFont;}- (UIColor *)detailsLabelColor {    return self.detailsLabel.textColor;}- (void)setDetailsLabelColor:(UIColor *)detailsLabelColor {    MBMainThreadAssert();    self.detailsLabel.textColor = detailsLabelColor;}- (CGFloat)opacity {    return _opacity;}- (void)setOpacity:(CGFloat)opacity {    MBMainThreadAssert();    _opacity = opacity;}- (UIColor *)color {    return self.bezelView.color;}- (void)setColor:(UIColor *)color {    MBMainThreadAssert();    self.bezelView.color = color;}- (CGFloat)yOffset {    return self.offset.y;}- (void)setYOffset:(CGFloat)yOffset {    MBMainThreadAssert();    self.offset = CGPointMake(self.offset.x, yOffset);}- (CGFloat)xOffset {    return self.offset.x;}- (void)setXOffset:(CGFloat)xOffset {    MBMainThreadAssert();    self.offset = CGPointMake(xOffset, self.offset.y);}- (CGFloat)cornerRadius {    return self.bezelView.layer.cornerRadius;}- (void)setCornerRadius:(CGFloat)cornerRadius {    MBMainThreadAssert();    self.bezelView.layer.cornerRadius = cornerRadius;}- (BOOL)dimBackground {    MBBackgroundView *backgroundView = self.backgroundView;    UIColor *dimmedColor =  [UIColor colorWithWhite:0.f alpha:.2f];    return backgroundView.style == MBProgressHUDBackgroundStyleSolidColor && [backgroundView.color isEqual:dimmedColor];}- (void)setDimBackground:(BOOL)dimBackground {    MBMainThreadAssert();    self.backgroundView.style = MBProgressHUDBackgroundStyleSolidColor;    self.backgroundView.color = dimBackground ? [UIColor colorWithWhite:0.f alpha:.2f] : [UIColor clearColor];}- (CGSize)size {    return self.bezelView.frame.size;}- (UIColor *)activityIndicatorColor {    return _activityIndicatorColor;}- (void)setActivityIndicatorColor:(UIColor *)activityIndicatorColor {    if (activityIndicatorColor != _activityIndicatorColor) {        _activityIndicatorColor = activityIndicatorColor;        UIActivityIndicatorView *indicator = (UIActivityIndicatorView *)self.indicator;        if ([indicator isKindOfClass:[UIActivityIndicatorView class]]) {            [indicator setColor:activityIndicatorColor];        }    }}@end@implementation MBProgressHUDRoundedButton#pragma mark - Lifecycle- (instancetype)initWithFrame:(CGRect)frame {    self = [super initWithFrame:frame];    if (self) {        CALayer *layer = self.layer;        layer.borderWidth = 1.f;    }    return self;}#pragma mark - Layout- (void)layoutSubviews {    [super layoutSubviews];    // Fully rounded corners    CGFloat height = CGRectGetHeight(self.bounds);    self.layer.cornerRadius = ceil(height / 2.f);}- (CGSize)intrinsicContentSize {    // Only show if we have associated control events    if (self.allControlEvents == 0) return CGSizeZero;    CGSize size = [super intrinsicContentSize];    // Add some side padding    size.width += 20.f;    return size;}#pragma mark - Color- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state {    [super setTitleColor:color forState:state];    // Update related colors    [self setHighlighted:self.highlighted];    self.layer.borderColor = color.CGColor;}- (void)setHighlighted:(BOOL)highlighted {    [super setHighlighted:highlighted];    UIColor *baseColor = [self titleColorForState:UIControlStateSelected];    self.backgroundColor = highlighted ? [baseColor colorWithAlphaComponent:0.1f] : [UIColor clearColor];}@end
 |