Iphone 在全球范围内使用MBProgressHUD+;让它成为单身
在我的项目中,每个用户交互事件都进行网络调用(这是TCP,而不是HTTP)。我需要活动指示器是全局的,以便从随机Iphone 在全球范围内使用MBProgressHUD+;让它成为单身,iphone,ios,singleton,mbprogresshud,Iphone,Ios,Singleton,Mbprogresshud,在我的项目中,每个用户交互事件都进行网络调用(这是TCP,而不是HTTP)。我需要活动指示器是全局的,以便从随机UIViewController显示,从NetworkActivityManager类隐藏(处理网络活动的自定义类,它不是UIViewController或UIView的子类) 搜索网页后,我发现MBProgressHUD用于相同的目的,但我无法找到如何在全球范围内使用它的示例。(所谓全局,我指的是MBProgressHUD的单例对象,以及显示和隐藏它的类方法。) 以下是我尝试过但失败
UIViewController
显示,从NetworkActivityManager
类隐藏(处理网络活动的自定义类,它不是UIViewController或UIView的子类)
搜索网页后,我发现MBProgressHUD用于相同的目的,但我无法找到如何在全球范围内使用它的示例。(所谓全局,我指的是MBProgressHUD的单例对象,以及显示和隐藏它的类方法。)
以下是我尝试过但失败的内容:
在AppDelegate.h中:
[SVProgressHUD show]; // Show
[SVProgressHUD dismiss]; // Dismiss
SVProgressHUD.show() // Show
SVProgressHUD.dismiss() // Dismiss
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss]; // OR SHOW, whatever the need is.
});
@属性(非原子,保留)MBProgressHUD*hud代码>
在AppDelegate.m中:
[SVProgressHUD show]; // Show
[SVProgressHUD dismiss]; // Dismiss
SVProgressHUD.show() // Show
SVProgressHUD.dismiss() // Dismiss
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss]; // OR SHOW, whatever the need is.
});
@合成hud代码>
在某些随机UIViewController对象中:
appDelegate.hud = [MBProgressHUD showHUDAddedTo:appDelegate.navigationController.topViewController.view animated:YES];
appDelegate.hud.labelText = @"This will take some time.";
隐藏时,从NetworkActivityManager
Class:
[MBProgressHUD hideHUDForView:appDelegate.navigationController.topViewController.view animated:YES];
这会使项目在一段时间后崩溃(由于内存问题)
我在我的项目中使用了ARC,而且我还使用了MBProgressHUD的ARC版本
我错过什么了吗
重要问题:
[SVProgressHUD show]; // Show
[SVProgressHUD dismiss]; // Dismiss
SVProgressHUD.show() // Show
SVProgressHUD.dismiss() // Dismiss
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss]; // OR SHOW, whatever the need is.
});
我可以使MBProgressHUD像UIAlertView一样工作吗?(我指的是独立于UIView的MBProgressHUD的实现——它使用showHUDAddedTo:
来呈现自身)
请注意:在上述隐藏MBProgressHUD的代码中,视图可能与显示MBProgressHUD时的视图不同
非常感谢您的帮助。我使用的方法如下..希望对您有所帮助
在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:@“加载..”currentView:presentView.view]代码>您可以将其添加到您喜欢的课程中:
+ (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之前请求新hud的情况。你可以在新的hud出现时隐藏以前的hud,或者出现某种排队等情况
在显示新的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;
}
答案是我现在使用的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。注意。。。
与许多iOS问题一样,这已经彻底过时了
这些天你肯定只是用了一个微不足道的
容器视图
对于任何像这样的问题
面向初学者的完整容器视图教程
MBHUD在当时是一个奇迹般的解决方案,因为苹果的管道上有一个“巨大的漏洞”
但是(就像过去许多美好的事情一样),现在这只是历史。今天不要做这种事
就在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步”等)
如果你愿意的话,可以把课文当作论据
你总是希望self.hud.minShowTime=0.1
以避免闪烁
几乎总是self.hud.dimBackground=YES这也会阻止用户界面
当然,从概念上讲,当您提出这样一个过程时,您通常必须“稍微等待”开始工作/结束工作,就像任何类似的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 \
)
这已经成为历史:)我发现@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)
}
上面的代码被放入一个全局文件中,我在其中保存了所有的全局帮助程序和常量。添加这两个方法以显示或隐藏singleton类中的加载程序
- (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];
}
注意:考虑到这个问题的观点,我决定以我选择的方式发布这篇文章作为解决方案这不是我问题的答案。(因此,接受的答案仍然被接受)
当时我最终使用了,因为集成和使用起来非常简单
只需将SVProgressHUD/SVProgressHUD文件夹拖动到项目中即可。(你也可以选择椰子荚或迦太基)
在Objective-C中:
[SVProgressHUD show]; // Show
[SVProgressHUD dismiss]; // Dismiss
SVProgressHUD.show() // Show
SVProgressHUD.dismiss() // Dismiss
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss]; // OR SHOW, whatever the need is.
});
在Swift中:
[SVProgressHUD show]; // Show
[SVProgressHUD dismiss]; // Dismiss
SVProgressHUD.show() // Show
SVProgressHUD.dismiss() // Dismiss
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss]; // OR SHOW, whatever the need is.
});
此外,需要在主线程上执行显示和隐藏HUD。(具体来说,您需要将HUD隐藏在背景中的某个闭合位置)
例如:
[SVProgressHUD show]; // Show
[SVProgressHUD dismiss]; // Dismiss
SVProgressHUD.show() // Show
SVProgressHUD.dismiss() // Dismiss
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss]; // OR SHOW, whatever the need is.
});
还有其他方法可用于使用HUD显示自定义消息、短期显示成功/失败和自动关闭
MBProgressHUD仍然是开发人员的好选择。只是我发现SVProgressHUD适合我的需要。我使用了@Michael Shang的代码,在显示HUD时有各种不一致的行为。事实证明,使用最后一个窗口是不可靠的,因为iOS键盘可能只是隐藏了它。因此,在大多数情况下,您应该使用AppDel获取窗口