MBProgressHUD + Customizations

Overview

MBProgressHUD

Build Status codecov.io SwiftPM compatible Carthage compatible Accio supported CocoaPods compatible License: MIT

MBProgressHUD is an iOS drop-in class that displays a translucent HUD with an indicator and/or labels while work is being done in a background thread. The HUD is meant as a replacement for the undocumented, private UIKit UIProgressHUD with some additional features.

Requirements

MBProgressHUD works on iOS 9.0+. It depends on the following Apple frameworks, which should already be included with most Xcode templates:

  • Foundation.framework
  • UIKit.framework
  • CoreGraphics.framework

You will need the latest developer tools in order to build MBProgressHUD. Old Xcode versions might work, but compatibility will not be explicitly maintained.

Adding MBProgressHUD to your project

CocoaPods

CocoaPods is the recommended way to add MBProgressHUD to your project.

  1. Add a pod entry for MBProgressHUD to your Podfile pod 'MBProgressHUD', '~> 1.2.0'
  2. Install the pod(s) by running pod install.
  3. Include MBProgressHUD wherever you need it with #import "MBProgressHUD.h".

Carthage

  1. Add MBProgressHUD to your Cartfile. e.g., github "jdg/MBProgressHUD" ~> 1.2.0
  2. Run carthage update
  3. Follow the rest of the standard Carthage installation instructions to add MBProgressHUD to your project.

SwiftPM / Accio

  1. Add the following to your Package.swift:
    .package(url: "https://github.com/jdg/MBProgressHUD.git", .upToNextMajor(from: "1.2.0")),
  2. Next, add MBProgressHUD to your App targets dependencies like so:
    .target(name: "App", dependencies: ["MBProgressHUD"]),
  3. Then open your project in Xcode 11+ (SwiftPM) or run accio update (Accio).

Source files

Alternatively you can directly add the MBProgressHUD.h and MBProgressHUD.m source files to your project.

  1. Download the latest code version or add the repository as a git submodule to your git-tracked project.
  2. Open your project in Xcode, then drag and drop MBProgressHUD.h and MBProgressHUD.m onto your project (use the "Product Navigator view"). Make sure to select Copy items when asked if you extracted the code archive outside of your project.
  3. Include MBProgressHUD wherever you need it with #import "MBProgressHUD.h".

Static library

You can also add MBProgressHUD as a static library to your project or workspace.

  1. Download the latest code version or add the repository as a git submodule to your git-tracked project.
  2. Open your project in Xcode, then drag and drop MBProgressHUD.xcodeproj onto your project or workspace (use the "Product Navigator view").
  3. Select your target and go to the Build phases tab. In the Link Binary With Libraries section select the add button. On the sheet find and add libMBProgressHUD.a. You might also need to add MBProgressHUD to the Target Dependencies list.
  4. Include MBProgressHUD wherever you need it with #import <MBProgressHUD/MBProgressHUD.h>.

Usage

The main guideline you need to follow when dealing with MBProgressHUD while running long-running tasks is keeping the main thread work-free, so the UI can be updated promptly. The recommended way of using MBProgressHUD is therefore to set it up on the main thread and then spinning the task, that you want to perform, off onto a new thread.

[MBProgressHUD showHUDAddedTo:self.view animated:YES];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
	// Do something...
	dispatch_async(dispatch_get_main_queue(), ^{
		[MBProgressHUD hideHUDForView:self.view animated:YES];
	});
});

You can add the HUD on any view or window. It is however a good idea to avoid adding the HUD to certain UIKit views with complex view hierarchies - like UITableView or UICollectionView. Those can mutate their subviews in unexpected ways and thereby break HUD display.

If you need to configure the HUD you can do this by using the MBProgressHUD reference that showHUDAddedTo:animated: returns.

MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.mode = MBProgressHUDModeAnnularDeterminate;
hud.label.text = @"Loading";
[self doSomethingInBackgroundWithProgressCallback:^(float progress) {
	hud.progress = progress;
} completionCallback:^{
	[hud hideAnimated:YES];
}];

You can also use a NSProgress object and MBProgressHUD will update itself when there is progress reported through that object.

MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.mode = MBProgressHUDModeAnnularDeterminate;
hud.label.text = @"Loading";
NSProgress *progress = [self doSomethingInBackgroundCompletion:^{
	[hud hideAnimated:YES];
}];
hud.progressObject = progress;

Keep in mind that UI updates, including calls to MBProgressHUD should always be done on the main thread.

If you need to run your long-running task in the main thread, you should perform it with a slight delay, so UIKit will have enough time to update the UI (i.e., draw the HUD) before you block the main thread with your task.

[MBProgressHUD showHUDAddedTo:self.view animated:YES];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
	// Do something...
	[MBProgressHUD hideHUDForView:self.view animated:YES];
});

You should be aware that any HUD updates issued inside the above block won't be displayed until the block completes.

For more examples, including how to use MBProgressHUD with asynchronous operations such as NSURLConnection, take a look at the bundled demo project. Extensive API documentation is provided in the header file (MBProgressHUD.h).

License

This code is distributed under the terms and conditions of the MIT license.

Change-log

A brief summary of each MBProgressHUD release can be found in the CHANGELOG.

Privacy

MBProgressHUD does not collect any data. See SDK Privacy Practices for more information.

Issues
  • KVO Setup crash in tests.

    KVO Setup crash in tests.

    So I'm using XCode 5 with XCTest + Expecta, All libraries installed with Cocoapods. Using ARC. Building for iOS 7.

    I can run my target on iOS simulator just fine, compiles, can't do every feature manually without a crash.

    When I run my tests, I have a failure that boils down to this method on addObserver with: EXC_BAD_ACCESS

    - (void)registerForKVO {
        for (NSString *keyPath in [self observableKeypaths]) {
            [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL]; // <-- EXC_BAD_ACCESS
        }
    }
    

    I invoke the HUD in my view controller like this:

    - (void)setupHud {
        self.hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
        [self.hud hide:NO];
    }
    

    Any ideas? Is this user error or a bug?

    opened by bobbytables 48
  • Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]

    Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]

    Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]

    opened by FlyingNoob 41
  • iOS 7 look and feel

    iOS 7 look and feel

    I'm looking for suggestions on how to change the default HUD style for iOS 7. One possibility would be a white bezel like this, or perhaps something than involves blurring the bezel or background aria?

    Enhancement 
    opened by matej 30
  • Resident Memory Bug

    Resident Memory Bug

    MBProgressHUD has been causing some memory issues within my project, and is reproducible within the Demo project. Whenever the HUD is shown / dismissed, there is an increase in the Dirty Memory Size (Visible within VM Tracker), and this is seemingly never released. Leading to a recurring growth in memory, eventually leading to memory warnings and the app being closed due to memory warnings.

    See http://d.pr/i/Kr0x (Every step up (after the initial spike) in the Dirty Size graph, is showing the progress HUD, when the hud is closed the memory is not cleared and keeps increasing.

    Whilst in this demo project the amount of memory is small, when using a custom view, with both label and details label, the memory consumed can be significantly higher.

    opened by sammio2 17
  • Add support for SwiftPM & Accio

    Add support for SwiftPM & Accio

    This adds support for SwiftPM manifest based dependency managers. Specifically this adds support for installing via Accio but may also work with SwiftPM once it's integrated into Xcode.

    Please note that this project is part of Accio's official integration tests within the Demo project.

    opened by Jeehut 15
  • Crash when changing mode on iOS 8 (iOS 7 and iOS 9 are ok)

    Crash when changing mode on iOS 8 (iOS 7 and iOS 9 are ok)

    I encountered a very strange behavior. When I change the mode of MBProgressHUD, I encounter a EXC_BAD_ACCESS in - (void)updatePaddingConstraints method. Specifically inside the block. This happens only on iOS 8 and is working just fine on iOS 7 and iOS 9. I tested on two devices: iPhone 5 and iPad 4, and the crash is very consistent. I enabled Address Sanitizer and Zombies, but all I found was that the first and second objects of self.paddingConstraints are zombies. This means that they were deallocated but somehow a reference to these objects still exist in self.paddingConstraints. Any idea what is going on?

    Following the method in the source code: (see ***** CRASH IS HERE ****** to the specific crash point)

    - (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;  // ***** CRASH IS HERE ******
            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 of if there's a visible view on top that yet doesn't have padding
            // added relative to the current view
            padding.constant = (firstVisible && (secondVisible || hasVisibleAncestors)) ? MBDefaultPadding : 0.f;
            hasVisibleAncestors |= secondVisible;
        }];
    }
    
    

    Following is the stack trace:

    (lldb) bt
    * thread #1: tid = 0x7e4b, 0x386376ba libobjc.A.dylib`objc_retain + 10, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x10000010)
        frame #0: 0x386376ba libobjc.A.dylib`objc_retain + 10
      * frame #1: 0x0008b2f8 TestMBProgressCrash`__41-[MBProgressHUD updatePaddingConstraints]_block_invoke(.block_descriptor=<unavailable>, padding=0x16d79610, idx=0, stop=NO) + 92 at MBProgressHUD.m:573
        frame #2: 0x29e8a2bc CoreFoundation`__53-[__NSArrayI enumerateObjectsWithOptions:usingBlock:]_block_invoke + 48
        frame #3: 0x29e8330e CoreFoundation`-[__NSArrayI enumerateObjectsWithOptions:usingBlock:] + 234
        frame #4: 0x0008b234 TestMBProgressCrash`-[MBProgressHUD updatePaddingConstraints](self=0x16d78610, _cmd="updatePaddingConstraints") + 228 at MBProgressHUD.m:572
        frame #5: 0x0008b114 TestMBProgressCrash`-[MBProgressHUD layoutSubviews](self=0x16d78610, _cmd="layoutSubviews") + 38 at MBProgressHUD.m:565
        frame #6: 0x2d5d9fd2 UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 546
        frame #7: 0x2cfedd28 QuartzCore`-[CALayer layoutSublayers] + 128
        frame #8: 0x2cfe955c QuartzCore`CA::Layer::layout_if_needed(CA::Transaction*) + 360
        frame #9: 0x2cfe93e4 QuartzCore`CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 16
        frame #10: 0x2cfe8d80 QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 224
        frame #11: 0x2cfe8b6e QuartzCore`CA::Transaction::commit() + 434
        frame #12: 0x2cfe2848 QuartzCore`CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 56
        frame #13: 0x29f25fec CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 20
        frame #14: 0x29f236aa CoreFoundation`__CFRunLoopDoObservers + 278
        frame #15: 0x29f23ab2 CoreFoundation`__CFRunLoopRun + 914
        frame #16: 0x29e70200 CoreFoundation`CFRunLoopRunSpecific + 476
        frame #17: 0x29e70012 CoreFoundation`CFRunLoopRunInMode + 106
        frame #18: 0x3182f200 GraphicsServices`GSEventRunModal + 136
        frame #19: 0x2d63ca08 UIKit`UIApplicationMain + 1440
        frame #20: 0x00085c98 TestMBProgressCrash`main(argc=1, argv=0x001f2abc) + 106 at main.m:14
        frame #21: 0x38bcfaae libdyld.dylib`start + 2
    
    Bug 
    opened by yoasha 14
  • Support for iOS 13 Dark Mode

    Support for iOS 13 Dark Mode

    Just curious if support for iOS 13 Dark Mode is planned in the near term, or if that is something you're looking for a PR on. Thanks!

    opened by jhammer 13
  • MBProgressHUD memory leaks

    MBProgressHUD memory leaks

    Found that memory is not released, it will crash the program runtime.

    untitled

    opened by leiyong316 13
  • for you add beauty

    for you add beauty

    Please forgive me, the first attempt to use github, thanks to satisfy my seeking knowledge desire

    Enhancement 
    opened by nanliSKy 12
  • HUD is not show when the keyboard is editing in iOS 11 ?

    HUD is not show when the keyboard is editing in iOS 11 ?

    In the textfield, When I have enter text incorrect in iOS11.0, HUD is not show, why ?

    opened by tiancl16 11
  • fix #605

    fix #605

    change: fix #605 add: modified grace time to 0 and show again

    opened by dagundejuzi 0
  • hud在Debug View Hierarchy上显示和我页面显示的效果不同

    hud在Debug View Hierarchy上显示和我页面显示的效果不同

    image image 奇怪的现在,我的界面显示hud被tableview遮挡,但是我打开图层显示在最上方,而且不管怎么调整显示的window还是无法做到在最上层显示,求解决办法

    opened by bosszhu 2
  • Fixed crash caused by continuous calls to

    Fixed crash caused by continuous calls to "setCustomView:" method

    UIImage *img = [UIImage imageNamed:@"hub_warning_icon"];
    UIImageView *customView = [[UIImageView alloc] initWithImage:img];
    for (NSUInteger i = 0; i < 2; i++) {
        
        MBProgressHUD *hud = [self toastToView:self.view];
        hud.mode = MBProgressHUDModeCustomView;
        [hud setCustomView:customView];
        hud.label.text = @"Title";
        hud.detailsLabel.text = @"Content";
        [hud hideAnimated:YES afterDelay:2];
    }
    

    The above code will crash, and the log is as follows:

    Thread 1: "Unable to install constraint on view. Does the constraint reference something from outside the subtree of the view? That's illegal. constraint:<NSLayoutConstraint:0x600003178870 UIImageView:0x151007950.centerX == MBBackgroundView:0x14fe48390.centerX (active)> view:<MBBackgroundView: 0x14fe48390; frame = (0 0; 0 0); clipsToBounds = YES; animations = { opacity=<CASpringAnimation: 0x600001258160>; }; layer = <CALayer: 0x600001260c60>>"

    opened by liLeiBest 0
  • swift package collection

    swift package collection

    I found many libraries such as RxSwift, Almofire has been added to the https://swiftpackageindex.com/ which allow the library to be added to XCode 13 natively. Is it possible to add this project to swift package index too?

    opened by holyman2k 0
  • pod

    pod "MBProgressHUD":失败

    [!] CocoaPods could not find compatible versions for pod "MBProgressHUD": In Podfile: MBProgressHUD (~> 1.2.0)

    None of your spec sources contain a spec satisfying the dependency: MBProgressHUD (~> 1.2.0).

    You have either:

    • out-of-date source repos which you can update with pod repo update or with pod install --repo-update.
    • mistyped the name or version.
    • not added the source repo that hosts the Podspec to your Podfile.
    opened by wangyan12 0
  • 关于扩展属性

    关于扩展属性

    1. @property (nonatomic, assign, readonly, getter=hasFinished) BOOL finished; 可否暴露这个属性 我想在自定义的时候更多扩展
    2. @property (assign, nonatomic) CGFloat verticalMargin UI_APPEARANCE_SELECTOR; 可否新增这个属性,因为默认 margin 是调整左右上下的间距,定制化的时候 我想可以单独调整上下的间距 [topSpacer addConstraint:[NSLayoutConstraint constraintWithItem:topSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:self.verticalMargin]]; [bottomSpacer addConstraint:[NSLayoutConstraint constraintWithItem:bottomSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:self.verticalMargin]];
    opened by fanlilinSaber 0
  • SPM- Package resolution failed

    SPM- Package resolution failed

    Hi, I am trying to add MBProgressHUD using SwiftPackageManager but Xcode is complaining about 'path' property of manifest file.

    Source files for target MBProgressHUD should be located under 'Sources/MBProgressHUD', or a custom sources path can be set with the 'path' property in Package.swift

    opened by chanuuuu 0
  • FR: Add in assets tag version XCFramework in a zip file

    FR: Add in assets tag version XCFramework in a zip file

    We'll in love if you could add in assets a xcframework zip file to download for this section.

    Thanks

    opened by jesusmateos1234 0
  • Can not hide loading

    Can not hide loading

    Loading cannot be closed when show and hide are executed on two consecutive requests.

    HUD address is as follows:

    // show: 0x1084b1bc0
    // hide:   0x1084b1bc0
    // show: 0x1084bddd0
    // hide:   0x10ba0dc30
    
    opened by xiaoMing0109 0
  • 加入.mm文件后mbp报错

    加入.mm文件后mbp报错

    新建一个类不写任何代码后缀改为.mm mbp会报错 WeChate04bc4f359ded7c37fe87ce992544fb3

    opened by ccccccccai 0
Owner
Jonathan George
I deliver results. Formerly CTO @Recurrency, CEO @Evomail , CEO @Boxcar. Love family, motorcycles and being an entrepreneur
Jonathan George
An extandable mosaic UICollectionViewLayout with a focus on extremely flexible customizations :large_orange_diamond:

SquareMosaicLayout An extandable mosaic UICollectionViewLayout with a focus on extremely flexible customizations. Note This layout is not of waterfall

Mikhail Vasilev 250 Dec 18, 2021