25

私のプロジェクトでは、各ユーザーインタラクションイベントがネットワーク呼び出しを行います(これはTCPであり、HTTPではありません)。ランダムから 表示し、クラス(UIViewControllerまたはUIViewのサブクラスではないネットワークアクティビティを処理するカスタムクラス)から非表示にするには、アクティビティインジケーターをグローバルにする必要があります。UIViewControllerNetworkActivityManager

Webを検索したところ、MBProgressHUDが同じ目的で使用されていることがわかりましたが、グローバルにどのように使用するかについての例を見つけることができませんでした。(グローバルとは、 MBProgressHUDのシングルトンオブジェクトと、それを表示および非表示にするクラスメソッドを意味します。)

以下は私がまだ試したものですが、失敗しました:AppDelegate.hで:

@property (nonatomic, retain) MBProgressHUD *hud;

AppDelegate.mの場合:

@synthesize hud;

いくつかのランダムなUIViewControllerオブジェクトでは:

appDelegate.hud = [MBProgressHUD showHUDAddedTo:appDelegate.navigationController.topViewController.view animated:YES];
appDelegate.hud.labelText = @"This will take some time.";

そしてそれを隠しながら、NetworkActivityManagerクラスから:

[MBProgressHUD hideHUDForView:appDelegate.navigationController.topViewController.view animated:YES];

これにより、しばらくするとプロジェクトがクラッシュします(メモリの問題が原因です)。プロジェクトでARCを使用しており、また、ARCバージョンのMBProgressHUDを使用しています。

私は何かが足りないのですか?

重要な質問:

MBProgressHUDをUIAlertViewのように機能させることはできますか?(私はUIViewから独立したMBProgressHUDshowHUDAddedTo:の実装を意味すると言っています-それはそれ自体を提示するために使用します)???

注意:上記のMBProgressHUDを非表示にするコードでは、MBProgressHUDを表示したときのビューから変更される場合があります。

どんな助けでも大歓迎です。

4

9 に答える 9

67

これを好みのクラスに追加できます。

+ (MBProgressHUD *)showGlobalProgressHUDWithTitle:(NSString *)title {
    UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject];
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:window animated:YES];
    hud.labelText = title;
    return hud;
}

+ (void)dismissGlobalHUD {
    UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject];
    [MBProgressHUD hideHUDForView:window animated:YES];
}

これは、どのクラスでも呼び出すことができます。これらのクラスの便利なメソッドを使用する場合、HUDへの強い参照を保持する必要はありません。

特定の状況によっては、他のハッドが非表示になる前に新しいハッドが要求された場合にも対処する必要があります。新しいものが入ってきたときや、ある種の待ち行列を思いついたときなどに、前のハッドを隠すことができます。

新しいインスタンスを表示する前に前のHUDインスタンスを非表示にするのは、非常に簡単です。

+ (MBProgressHUD *)showGlobalProgressHUDWithTitle:(NSString *)title {
    UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject];
    [MBProgressHUD hideAllHUDsForView:window animated:YES];
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:window animated:YES];
    hud.labelText = title;
    return hud;
}
于 2012-08-22T11:40:17.350 に答える
8

ノート...

多くのiOSの問題と同様に、これは今では大幅に、完全に時代遅れになっています。

最近は確かに些細なことを使うだけです

コンテナビュー

このような問題のために。

初心者のための完全なコンテナビューチュートリアル..チュートリアル!

MBProgressHUDは、Appleのパイプラインに「劇的な穴」があったため、当時は奇跡的なソリューションでした。

しかし(過去の多くの素晴らしいものと同様に)、これは今の歴史に過ぎません。今日はこのようなことをしないでください。


ちょうどFWIW、2014年、これが私たちが使用する非常に簡単なセットアップです。デビッド・ローソンによる...

UIWindow *window = [[UIApplication sharedApplication] delegate].window

Matejが言うように、AppDelegateを使用するだけです...

#define APP ((AppDelegate *)[[UIApplication sharedApplication] delegate])

AppDelegate.h

// our convenient huddie system (messages with a hud, spinner)
@property (nonatomic, strong) MBProgressHUD *hud;
-(void)huddie;

AppDelegate.m

-(void)huddie
{
// centralised location for MBProgressHUD
[self.hud hide:YES];

UIWindow *windowForHud = [[UIApplication sharedApplication] delegate].window;
self.hud = [MBProgressHUD showHUDAddedTo:windowForHud animated:YES];

self.hud.dimBackground = YES;
self.hud.minShowTime = 0.1;
self.hud.labelText = @"";
self.hud.detailsLabelText = @"";
}

実行中に頻繁にタイトルを変更するため、使用しているコードのタイトルを設定します。(「ステップ1」...「ステップ2」など)

-(void)loadBlahFromCloud
{
[APP huddie];
APP.hud.labelText = @"Connecting to Parse...";
APP.hud.detailsLabelText = @"step 1/2";

[blah refreshFromCloudThen:
    ^{
    [... example];
    }];
}

-(void)example
{
APP.hud.labelText = @"Connecting to the bank...";
APP.hud.detailsLabelText = @"step 2/2";

[blah sendDetailsThen:
    ^{
    [APP.hud hide:YES];
    [...  showNewDisplay];
    }];
}

必要に応じて、ハドルを変更して、テキストを引数として使用します

常にself.hud.minShowTime=0.1が必要です。ちらつきを避けるために

ほとんどの場合、self.hud.dimBackground = YES; UIもブロックします

概念的にはもちろん、UIを使用した同様のプログラミングと同様に、このようなプロセスを開始するときは、通常、作業を開始/終了するために「少し待つ」必要があります。

したがって、実際には、コードは通常次のようになります...

-(void)loadActionSheets
{
[APP huddie];
APP.hud.labelText = @"Loading json from net...";

dispatch_after_secs_on_main(0.1 ,
    ^{
    [STUBS refreshNowFromCloudThen:
        ^{
        [APP.hud hide:YES];
        dispatch_after_secs_on_main(0.1 , ^{ [self buildActionsheet]; });
        }];
        }
    );
}

便利なマクロ..

#define dispatch_after_secs_on_main( SS, BB )                   \
        dispatch_after(                                         \
            dispatch_time(DISPATCH_TIME_NOW, SS*NSEC_PER_SEC),  \
            dispatch_get_main_queue(),                          \
            BB                                                  \
            )

これは今のすべての歴史です: )https://stackoverflow.com/a/23403979/294884

于 2014-04-14T09:04:54.720 に答える
3

この答えは、ブロック内でも完全に機能するため、現在5〜6個のアプリで使用しているものです。しかし、私はそれに問題を見つけました。表示させることはできますが、UIAlertViewも存在する場合は非表示にすることはできません。実装を見ると、その理由がわかります。これに変更するだけです:

static UIWindow *window;

+ (MBProgressHUD *)showGlobalProgressHUDWithTitle:(NSString *)title {

    window = [[[UIApplication sharedApplication] windows] lastObject];
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:window animated:YES];
    hud.labelText = title;

    return hud;
}

+ (void)dismissGlobalHUD {

    [MBProgressHUD hideHUDForView:window animated:YES];
}

これにより、表示されたのと同じウィンドウからHUDを削除していることを確認できます。

于 2013-06-12T13:22:31.787 に答える
2

@Matej Bukovinskiの回答は非常に役に立ちました。Swiftを使い始めたばかりで、彼のメソッドを使用する目的はMBProgressHUDのグローバルフォントを設定することだったので、コードをswiftに変換し、以下のコードを共有したいと思います。

class func showGlobalProgressHUDWithTitle(title: String) -> MBProgressHUD{
    let window:UIWindow = UIApplication.sharedApplication().windows.last as! UIWindow
    let hud = MBProgressHUD.showHUDAddedTo(window, animated: true)
    hud.labelText = title
    hud.labelFont = UIFont(name: FONT_NAME, size: 15.0)
    return hud
}

class func dismissGlobalHUD() -> Void{
    let window:UIWindow = UIApplication.sharedApplication().windows.last as! UIWindow
    MBProgressHUD.hideAllHUDsForView(window, animated: true)
}

上記のコードはグローバルファイルに入れられ、すべてのグローバルヘルパーと定数が保持されます。

于 2015-08-24T03:15:31.647 に答える
1

私はそれを以下のように使用しました..それがあなたを助けることを願っています..

appDelegate.m

-(void)showIndicator:(NSString *)withTitleString currentView:(UIView *)currentView
{ 
if (!isIndicatorStarted) {

    // The hud will dispable all input on the view
    self.progressHUD = [[[MBProgressHUD alloc] initWithView:currentView] autorelease]; 
    // Add HUD to screen 
    [currentView addSubview:self.progressHUD]; 
    self.progressHUD.labelText = withTitleString;
    [window setUserInteractionEnabled:FALSE];
    [self.progressHUD show:YES];

    isIndicatorStarted = TRUE;
}   
 } 

-(void)hideIndicator 
{ 

    [self.progressHUD show:NO]; 
    [self.progressHUD removeFromSuperview]; 
    self.progressHUD = nil;
    [window setUserInteractionEnabled:TRUE];
    isIndicatorStarted = FALSE;
}

ランダムビューから:-

[appDel showIndicator:@"Loading.." currentView:presentView.view];

于 2012-08-20T06:35:28.377 に答える
1

:この質問の見解を考慮して、解決策として選択した方法を投稿することにしました。これは私の質問に対する答えではありません。(したがって、受け入れられた回答は受け入れられたままです)

統合と使用が非常に簡単だったため、当時はSVProgressHUDを使用することになりました。

必要なのは、SVProgressHUD/SVProgressHUDフォルダーをプロジェクトにドラッグすることだけです。(ココアポッドまたはカーセージを選択することもできます)


Objective-Cの場合:

[SVProgressHUD show]; // Show
[SVProgressHUD dismiss]; // Dismiss

Swiftの場合:

SVProgressHUD.show() // Show
SVProgressHUD.dismiss() // Dismiss

さらに、HUDの表示と非表示をメインスレッドで実行する必要があります。(具体的には、バックグラウンドでいくつかのクロージャーでHUDを非表示にするためにこれが必要になります)

例えば:

dispatch_async(dispatch_get_main_queue(), ^{
    [SVProgressHUD dismiss]; // OR SHOW, whatever the need is.
});

HUDを使用してカスタムメッセージを表示し、短時間の成功/失敗と自動却下を表示するための追加の方法があります。

MBProgressHUDは、依然として開発者にとって良い選択です。自分のニーズに合ったSVProgressHUDを見つけただけです。

于 2016-06-30T13:52:51.140 に答える
0

私は@MichaelShangのコードを使用していて、HUDの表示に関してあらゆる種類の一貫性のない動作をしていました。最後のウィンドウを使用すると、iOSキーボードがウィンドウを非表示にする可能性があるため、信頼性が低くなります。したがって、ほとんどの場合、@ David Lawsonが述べているように、AppDelegateを使用してウィンドウを取得する必要があります。

Swiftでの方法は次のとおりです。

let window = UIApplication.sharedApplication().delegate!.window!!
let hud = MBProgressHUD.showHUDAddedTo(window, animated: true)

ただし、上記の場合、HUDはiOSキーボードの後ろに表示されます(重なっている場合)。キーボードをオーバーレイするためにHUDが必要な場合は、ラストウィンドウ方式を使用してください。

私の場合、何が起こっていたのかというと、HUDを表示しresignFirstResponder()てから、HUDが追加されたウィンドウをすぐに非表示にして呼び出します。ですから、これは注意すべきことです。固執することが保証されている唯一のウィンドウは最初のウィンドウです。

必要に応じて、キーボードの上にHUDをオプションで追加できるメソッドを作成することになりました。

func createHUD(size: CGSize, overKeyboard: Bool = false) -> MBProgressHUD {
    let window = overKeyboard ? UIApplication.sharedApplication().windows.last!
                              : UIApplication.sharedApplication().delegate!.window!!
    let hud = MBProgressHUD.showHUDAddedTo(window, animated: true)
    hud.minSize = size
    hud.bezelView.style = .SolidColor
    hud.bezelView.color = UIColor(white: 0, alpha: 0.8)
    return hud
}
于 2016-11-27T03:00:50.700 に答える
0

一度に表示するには、MBProgressHUD天気HUDがすでに同じビューに追加されているかどうかを確認できます。そうでない場合は、HUDを追加します。それ以外の場合は、新しいHUDを追加しないでください。

-(void)showLoader{    
    dispatch_async(dispatch_get_main_queue(), ^{
        BOOL isHudAlreadyAdded = false;

        UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject];
        NSEnumerator *subviewsEnum = [window.subviews reverseObjectEnumerator];
        for (UIView *subview in subviewsEnum) {
            if ([subview isKindOfClass:[MBProgressHUD class]]) {
                isHudAlreadyAdded = true;
            }
        }
        if(isHudAlreadyAdded == false){
            [MBProgressHUD showHUDAddedTo:window animated:YES];
        }
    });
}

-(void)hideLoader{
    dispatch_async(dispatch_get_main_queue(), ^{
        UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject];
        [MBProgressHUD hideHUDForView:window animated:YES];
    });
}
于 2017-06-28T12:37:51.033 に答える
-1

これらの2つのメソッドを追加して、シングルトンクラスでローダーを表示または非表示にします

- (void)startLoaderWithText:(NSString *)title View:(UIView *)view{
    progressHud = [MBProgressHUD showHUDAddedTo:view animated:YES];
    progressHud.labelText = title;
    progressHud.activityIndicatorColor = [UIColor grayColor];
    progressHud.color = [UIColor clearColor];
    [progressHud show:YES];
}

- (void)stopLoader{
    [progressHud hide:YES];
}
于 2016-06-01T07:28:17.960 に答える