| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194 | 
							- //
 
- // MBProgressHUD.m
 
- // Version 1.2.0
 
- // Created by Matej Bukovinski on 2.4.09.
 
- //
 
- #import "MBProgressHUD.h"
 
- #import <tgmath.h>
 
- #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 ()
 
- @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, strong) UIMotionEffectGroup *bezelMotionEffects;
 
- @property (nonatomic, weak) NSTimer *graceTimer;
 
- @property (nonatomic, weak) NSTimer *minShowTimer;
 
- @property (nonatomic, weak) NSTimer *hideDelayTimer;
 
- @property (nonatomic, weak) CADisplayLink *progressObjectDisplayLink;
 
- @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]) {
 
-             MBProgressHUD *hud = (MBProgressHUD *)subview;
 
-             if (hud.hasFinished == NO) {
 
-                 return hud;
 
-             }
 
-         }
 
-     }
 
-     return nil;
 
- }
 
- #pragma mark - Lifecycle
 
- - (void)commonInit {
 
-     // Set default values for properties
 
-     _animationType = MBProgressHUDAnimationFade;
 
-     _mode = MBProgressHUDModeIndeterminate;
 
-     _margin = 20.0f;
 
-     _defaultMotionEffectsEnabled = NO;
 
-     if (@available(iOS 13.0, tvOS 13, *)) {
 
-        _contentColor = [[UIColor labelColor] colorWithAlphaComponent:0.7f];
 
-     } else {
 
-         _contentColor = [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 {
 
-     // Cancel any scheduled hideAnimated:afterDelay: calls
 
-     [self.hideDelayTimer invalidate];
 
-     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 hideAnimated:afterDelay: 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];
 
-     // Set up motion effects only at this point to avoid needlessly
 
-     // creating the effect if it was disabled after initialization.
 
-     [self updateBezelMotionEffects];
 
-     if (animated) {
 
-         [self animateIn:YES withType:self.animationType completion:NULL];
 
-     } else {
 
-         self.bezelView.alpha = 1.f;
 
-         self.backgroundView.alpha = 1.f;
 
-     }
 
- }
 
- - (void)hideUsingAnimation:(BOOL)animated {
 
-     // Cancel any scheduled hideAnimated:afterDelay: calls.
 
-     // This needs to happen here instead of in done,
 
-     // to avoid races if another hideAnimated:afterDelay:
 
-     // call comes in while the HUD is animating out.
 
-     [self.hideDelayTimer invalidate];
 
-     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;
 
-         }
 
-         CGFloat alpha = animatingIn ? 1.f : 0.f;
 
-         bezelView.alpha = alpha;
 
-         self.backgroundView.alpha = alpha;
 
-     };
 
-     [UIView animateWithDuration:0.3 delay:0. usingSpringWithDamping:1.f initialSpringVelocity:0.f options:UIViewAnimationOptionBeginFromCurrentState animations:animations completion:completion];
 
- }
 
- - (void)done {
 
-     [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;
 
-     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
 
-             UIActivityIndicatorView *activityIndicator;
 
-             [indicator removeFromSuperview];
 
- #if !TARGET_OS_MACCATALYST
 
-             if (@available(iOS 13.0, tvOS 13.0, *)) {
 
- #endif
 
-                 activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge];
 
-                 activityIndicator.color = [UIColor whiteColor];
 
- #if !TARGET_OS_MACCATALYST
 
-             } else {
 
-                activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
 
-             }
 
- #endif
 
-             [activityIndicator startAnimating];
 
-             indicator = activityIndicator;
 
-             [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];
 
-     // 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 = [color colorWithAlphaComponent:0.1];
 
-         }
 
-     } 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 {
 
-         [indicator setTintColor:color];
 
-     }
 
- }
 
- - (void)updateBezelMotionEffects {
 
-     MBBackgroundView *bezelView = self.bezelView;
 
-     UIMotionEffectGroup *bezelMotionEffects = self.bezelMotionEffects;
 
-     if (self.defaultMotionEffectsEnabled && !bezelMotionEffects) {
 
-         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];
 
-         self.bezelMotionEffects = group;
 
-         [bezelView addMotionEffect:group];
 
-     } else if (bezelMotionEffects) {
 
-         self.bezelMotionEffects = nil;
 
-         [bezelView removeMotionEffect:bezelMotionEffects];
 
-     }
 
- }
 
- #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 && !TARGET_OS_MACCATALYST
 
-     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
 
-     [nc addObserver:self selector:@selector(statusBarOrientationDidChange:)
 
-                name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
 
- #endif
 
- }
 
- - (void)unregisterFromNotifications {
 
- #if !TARGET_OS_TV && !TARGET_OS_MACCATALYST
 
-     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
 
-     [nc removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
 
- #endif
 
- }
 
- #if !TARGET_OS_TV && !TARGET_OS_MACCATALYST
 
- - (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.frame = 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];
 
-     }
 
-     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 = backgroundTintColor;
 
-         [self setNeedsDisplay];
 
-     }
 
- }
 
- #pragma mark - Drawing
 
- - (void)drawRect:(CGRect)rect {
 
-     CGContextRef context = UIGraphicsGetCurrentContext();
 
-     if (_annular) {
 
-         // Draw background
 
-         CGFloat lineWidth = 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 = 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);
 
-         CGContextStrokeEllipseInRect(context, circleRect);
 
-         // 90 degrees
 
-         CGFloat startAngle = - ((float)M_PI / 2.f);
 
-         // Draw progress
 
-         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 overlapping 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 {
 
-     return CGSizeMake(120.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 and Border
 
-     CGFloat radius = (rect.size.height / 2) - 2;
 
-     CGContextMoveToPoint(context, 2, rect.size.height/2);
 
-     CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius);
 
-     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);
 
-     CGContextAddArcToPoint(context, 2, rect.size.height - 2, 2, rect.size.height/2, radius);
 
-     CGContextDrawPath(context, kCGPathFillStroke);
 
-     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 ()
 
- @property UIVisualEffectView *effectView;
 
- @end
 
- @implementation MBBackgroundView
 
- #pragma mark - Lifecycle
 
- - (instancetype)initWithFrame:(CGRect)frame {
 
-     if ((self = [super initWithFrame:frame])) {
 
-         _style = MBProgressHUDBackgroundStyleBlur;
 
-         if (@available(iOS 13.0, *)) {
 
-             #if TARGET_OS_TV
 
-             _blurEffectStyle = UIBlurEffectStyleRegular;
 
-             #else
 
-             _blurEffectStyle = UIBlurEffectStyleSystemThickMaterial;
 
-             #endif
 
-             // Leaving the color unassigned yields best results.
 
-         } else {
 
-             _blurEffectStyle = UIBlurEffectStyleLight;
 
-             _color = [UIColor colorWithWhite:0.8f alpha:0.6f];
 
-         }
 
-         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 != 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];
 
-     }
 
- }
 
- - (void)setBlurEffectStyle:(UIBlurEffectStyle)blurEffectStyle {
 
-     if (_blurEffectStyle == blurEffectStyle) {
 
-         return;
 
-     }
 
-     _blurEffectStyle = blurEffectStyle;
 
-     [self updateForBackgroundStyle];
 
- }
 
- ///////////////////////////////////////////////////////////////////////////////////////////
 
- #pragma mark - Views
 
- - (void)updateForBackgroundStyle {
 
-     [self.effectView removeFromSuperview];
 
-     self.effectView = nil;
 
-     MBProgressHUDBackgroundStyle style = self.style;
 
-     if (style == MBProgressHUDBackgroundStyleBlur) {
 
-         UIBlurEffect *effect =  [UIBlurEffect effectWithStyle:self.blurEffectStyle];
 
-         UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
 
-         [self insertSubview:effectView atIndex:0];
 
-         effectView.frame = self.bounds;
 
-         effectView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
 
-         self.backgroundColor = self.color;
 
-         self.layer.allowsGroupOpacity = NO;
 
-         self.effectView = effectView;
 
-     } else {
 
-         self.backgroundColor = self.color;
 
-     }
 
- }
 
- - (void)updateViewsForColor:(UIColor *)color {
 
-     if (self.style == MBProgressHUDBackgroundStyleBlur) {
 
-         self.backgroundColor = self.color;
 
-     } else {
 
-         self.backgroundColor = self.color;
 
-     }
 
- }
 
- @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 and a title
 
-     if ((self.allControlEvents == 0) || ([self titleForState:UIControlStateNormal].length == 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
 
 
  |