手机怎样设置才能在固定时间不用的什么情况下才能贴封条自动关闭后台运行程序?

MBProgressHUD是一个显示HUD窗口的第三方类库,用于在执行一些后台任务时,在程序中显示一个表示进度的loading视图和两个可选的文本提示的HUD窗口。我想最多是应用在加载网络数据的时候。其实苹果官方自己有一个带有此功能的类UIProgressHUD,只不过它是私有的,现在不让用。至于实际的效果,可以看看github上工程给出的几张图例(貌似我这经常无法单独打开图片,所以就不在这贴图片了),也可以运行一下Demo。
具体用法我们就不多说了,参考github上的说明就能用得很顺的。本文主要还是从源码的角度来分析一下它的具体实现。
在分析实现代码之前,我们先来看看MBProgressHUD中定义的MBProgressHUDMode枚举。它用来表示HUD窗口的模式,即我们从效果图中看到的几种显示样式。其具体定义如下:
typedef enum {
通过设置MBProgressHUD的模式,我们可以使用MBProgressHUD自定义的表示进度的视图来满足我们的需求,也可以自定义这个进度视图,当然还可以只显示文本。在下面我们会讨论源码中是如何使用这几个值的。
我们先来了解一下MBProgressHUD的基本组成。一个MBProgressHUD视图主要由四个部分组成:
loading动画视图(在此做个统称,当然这个区域可以是自定义的一个UIImageView视图)。这个视图由我们设定的模式值决定,可以是菊花、进度条,也可以是我们自定义的视图;
标题文本框(label):主要用于显示提示的主题信息。这个文本框是可选的,通常位于loading动画视图的下面,且它是单行显示。它会根据labelText属性来自适应文本的大小(有一个长度上限),如果过长,则超出的部分会显示为&&&;
详情文本框(detailsLabel)。如果觉得标题不够详细,或者有附属信息,就可以将详细信息放在这里面显示。该文本框对应的是显示detailsLabelText属性的值,它是可以多行显示的。另外,详情的显示还依赖于labelText属性的设置,只有labelText属性被设置了,且不为空串,才会显示detailsLabel;
HUD背景框。主要是作为上面三个部分的一个背景,用来突出上面三部分。
为了让我们更好地自定义这几个部分,MBProgressHUD还提供了一些属性,我们简单了解一下:
@property (assign)
float cornerR
@property (MB_STRONG) UIColor* labelC
通过以上属性,我们可以根据自己的需要来设置这几个部分的外观。
另外还有一个比较有意思的属性是dimBackground,用于为HUD窗口的视图区域覆盖上一层径向渐变(radial gradient)层,其定义如下:
@property (assign) BOOL dimB
让我们来看看通过它,MBProgressHUD都做了些什么。代码如下:
- (void)drawRect:(CGRect)rect {
if (self.dimBackground)
CGContextDrawRadialGradient (context, gradient, gradCenter,
0, gradCenter, gradRadius,
kCGGradientDrawsAfterEndLocation);
CGGradientRelease(gradient);
这段代码由中心向MBProgressHUD视图的四周绘制了一个渐变层。当然,这里的颜色值是写死的,我们无法自行定义。有兴趣的话,大家可以将这个属性设置为YES,看看实际的效果。
创建、布局与绘制
除了继承自UIView的-initWithFrame:初始化方法,MBProgressHUD还为我们提供了两个初始化方法,如下所示:
- (id)initWithWindow:(UIWindow *) - (id)initWithView:(UIView *)
这两个方法分别传入一个UIWindow对象和一个UIView对象。传入的视图对象仅仅是做为MBProgressHUD视图定义其frame属性的参照,而不会直接将MBProgressHUD视图添加到传入的视图对象上。这个添加操作还得我们自行处理(当然,MBProgressHUD还提供了几个便捷的类方法,我们下面会说明)。
MBProgressHUD提供了几个属性,可以让我们控制HUD的布局,这些属性主要有以下几个:
需要注意的是,MBProgressHUD视图会充满其父视图的frame内,为此,在MBProgressHUD的layoutSubviews方法中,还专门做了处理,如下代码所示:
- (void)layoutSubviews {
[super layoutSubviews];
也因此,当MBProgressHUD显示时,它也会屏蔽父视图的各种交互操作。
在布局的过程中,会先根据我们要显示的视图计算出容纳这些视图所需要的总的宽度和高度。当然,会设置一个最大值。我们截取其中一段来看看:
CGRect bounds = self.
... CGFloat remainingHeight = bounds.size.height - totalSize.height - kPadding - 4 *
CGSize maxSize = CGSizeMake(maxWidth, remainingHeight);
CGSize detailsLabelSize = MB_MULTILINE_TEXTSIZE(detailsLabel.text, detailsLabel.font, maxSize, detailsLabel.lineBreakMode);
totalSize.width = MAX(totalSize.width, detailsLabelSize.width); totalSize.height += detailsLabelSize.
if (detailsLabelSize.height & 0.f && (indicatorF.size.height & 0.f || labelSize.height & 0.f)) {
totalSize.height += kP } totalSize.width += 2 * totalSize.height += 2 *
之后,就开始从上到下放置各个视图。在布局代码的最后,计算了一个size值,这是为后面绘制背景框做准备的。
在上面的布局代码中,主要是处理了loading动画视图、标题文本框和详情文本框,而HUD背景框主要是在drawRect:中来绘制的。背景框的绘制代码如下:
这是最平常的绘制操作,在此不多做解释。
我们上面讲过MBProgressHUD提供了几种窗口模式,这几种模式的主要区别在于loading动画视图的展示。默认情况下,使用的是菊花(MBProgressHUDModeIndeterminate)。我们可以通过设置以下属性,来改变loading动画视图:
@property (assign) MBProgressHUDM
对于其它几种模式,MBProgressHUD专门我们提供了几个视图类。如果是进度条模式(MBProgressHUDModeDeterminateHorizontalBar),则使用的是MBBarProgressView类;如果是饼图模式(MBProgressHUDModeDeterminate)或环形模式(MBProgressHUDModeAnnularDeterminate),则使用的是MBRoundProgressView类。上面这两个类的主要操作就是在drawRect:中根据一些进度参数来绘制形状,大家可以自己详细看一下。
当然,我们还可以自定义loading动画视图,此时选择的模式是MBProgressHUDModeCustomView。或者不显示loading动画视图,而只显示文本框(MBProgressHUDModeText)。
具体显示哪一种loading动画视图,是在-updateIndicators方法中来处理的,其实现如下所示:
- (void)updateIndicators {
BOOL isActivityIndicator = [indicator isKindOfClass:[UIActivityIndicatorView class]];
BOOL isRoundIndicator = [indicator isKindOfClass:[MBRoundProgressView class]];
if (mode == MBProgressHUDModeIndeterminate) {
else if (mode == MBProgressHUDModeDeterminateHorizontalBar)
// Update to bar determinate indicator
[indicator removeFromSuperview];
self.indicator = MB_AUTORELEASE([[MBBarProgressView alloc] init]);
[self addSubview:indicator];
else if (mode == MBProgressHUDModeDeterminate || mode == MBProgressHUDModeAnnularDeterminate)
if (!isRoundIndicator) {
if (mode == MBProgressHUDModeAnnularDeterminate)
[(MBRoundProgressView *)indicator setAnnular:YES];
else if (mode == MBProgressHUDModeCustomView && customView != indicator)
} else if (mode == MBProgressHUDModeText)
显示与隐藏
MBRoundProgressView为我们提供了丰富的显示与隐藏HUD窗口的。在分析这些方法之前,我们先来看看MBProgressHUD为显示与隐藏提供的一些属性:
以上这些属性都还好理解,可能需要注意的就是graceTime和taskInProgress的配合使用。在下面我们将会看看这两个属性的用法。
对于显示操作,最基本的就是-show:方法(其它几个显示方法都会调用该方法来显示HUD窗口),我们先来看看它的实现,
- (void)show:(BOOL)animated
& & useAnimation =
可以看到,如果我们没有设置graceTime属性,则会立即显示HUD;而如果设置了graceTime,则会创建一个定时器,并让显示操作延迟到graceTime所设定的时间再执行,而-handleGraceTimer:实现如下:
- (void)handleGraceTimer:(NSTimer *)theTimer
// Show the HUD only if the task is still running if (taskInProgress)
{ [self showUsingAnimation:useAnimation];
可以看到,只有在设置了taskInProgress标识位为YES的情况下,才会去显示HUD窗口。所以,如果我们要自己调用-show:方法的话,需要酌情考虑设置taskInProgress标识位。
除了-show:方法以外,MBProgressHUD还为我们提供了一组显示方法,可以让我们在显示HUD的同时,执行一些后台任务,我们在此主要介绍两个。其中一个是-showWhileExecuting:onTarget:withObject:animated:,它是基于target-action方式的调用,在执行一个后台任务时显示HUD,等后台任务执行完成后再隐藏HUD,具体实现如下所示:
- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated
methodForExecution =
targetForExecution = MB_RETAIN(target);
objectForExecution = MB_RETAIN(object);
// Launch execution in new thread
self.taskInProgress = YES;
[NSThread detachNewThreadSelector:@selector(launchExecution) toTarget:self withObject:nil];
// Show HUD view
[self show:animated];
- (void)launchExecution
@autoreleasepool
{ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
// Start executing the requested task
[targetForExecution performSelector:methodForExecution withObject:objectForExecution];
#pragma clang diagnostic pop
// Task completed, update view in main thread (note: view operations should&be done only in the main thread)
[self performSelectorOnMainThread:@selector(cleanUp) withObject:nil waitUntilDone:NO];
可以看到,-showWhileExecuting:onTarget:withObject:animated:首先将taskInProgress属性设置为YES,这样在调用-show:方法时,即使设置了graceTime,也确保能在任务完成之前显示HUD。然后开启一个新线程,来异步执行我们的后台任务,最后去显示HUD。
而在异步调用方法-launchExecution中,线程首先是维护了自己的一个@autoreleasepool,所以在我们自己的方法中,就不需要再去维护一个@autoreleasepool了。之后是去执行我们的任务,在任务完成之后,再回去主线程去执行清理操作,并隐藏HUD窗口。
另一个显示方法是-showAnimated:whileExecutingBlock:onQueue:completionBlock:,它是基于GCD的调用,当block中的任务在指定的队列中执行时,显示HUD窗口,任务完成之后执行completionBlock操作,最后隐藏HUD窗口。我们来看看它的具体实现:
- (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue
     completionBlock:(MBProgressHUDCompletionBlock)completion
self.taskInProgress = YES;
pletionBlock =
dispatch_async(queue, ^(void) {
       block();
dispatch_async(dispatch_get_main_queue(), ^(void)
[self cleanUp];
      
     
  [self show:animated];       
这个方法也是首先将taskInProgress属性设置为YES,然后开启一个线程去执行block任务,最后主线程去执行清理操作,并隐藏HUD窗口。
对于HUD的隐藏,MBProgressHUD提供了两个方法,一个是-hide:,另一个是-hide:afterDelay:,后者基于前者,所以我们主要来看看-hide:的实现:
- (void)hide:(BOOL)animated
& &useAnimation =
我们可以看到,在设置了minShowTime属性并且已经显示了HUD窗口的情况下,会去判断显示的时间是否小于minShowTime指定的时间,如果是,则会开启一个定时器,等到显示的时间到了minShowTime所指定的时间,才会去隐藏HUD窗口;否则会直接去隐藏HUD窗口。
隐藏的实际操作主要是去做了些清理操作,包括根据设定的removeFromSuperViewOnHide值来执行是否从父视图移除HUD窗口,以及执行completionBlock操作,还有就是执行代理的hudWasHidden:方法。这些操作是在私有方法-done里面执行的,实现如下:
- (void)done
[NSObject cancelPreviousPerformRequestsWithTarget:self];
isFinished = YES;
self.alpha = 0.0f;
if (removeFromSuperViewOnHide)
[self removeFromSuperview];
MBProgressHUD的一些主要的代码差不多已经分析完了,最后还有些边边角角的地方,一起来看看。
显示和隐藏的便捷方法
除了上面描述的实例方法之外,MBProgressHUD还为我们提供了几个便捷显示和隐藏HUD窗口的方法,如下所示:
方法的签名已经很能说明问题了,在此不多描述。
部分属性值的设置
对于部分属性(主要是&外观&一节中针对菊花、标题文本框和详情文本框的几个属性值),为了在设置将这些属性时修改对应视图的属性,并没有直接为每个属性生成一个setter,而是通过KVO来监听这些属性值的变化,再将这些值赋值给视图的对应属性,如下所示:
MBProgressHUD还为我们提供了一个代理MBProgressHUDDelegate,这个代理中只提供了一个方法,即:
- (void)hudWasHidden:(MBProgressHUD *)
这个代理方法是在隐藏HUD窗口后调用,如果此时我们需要在我们自己的实现中执行某些操作,则可以实现这个方法。
MBProgressHUD为我们提供了一个HUD窗口的很好的实现,不过个人在使用过程中,觉得它给我们提供的交互功能太少。其代理只提供了一个-hudWasHidden:方法,而且我们也无法通过点击HUD来执行一些操作。在现实的需求中,可能存在这种情况:比如一个网络操作,在发送请求等待响应的过程中,我们会显示一个HUD窗口以显示一个loading框。但如果我们想在等待响应的过程中,在当前视图中取消这个网络请求,就没有相应的处理方式,MBProgressHUD没有为我们提供这样的交互操作。当然这时候,我们可以根据自己的需求来修改源码。
与SVProgressHUD的对比
与MBProgressHUD类似,SVProgressHUD类库也为我们提供了在视图中显示一个HUD窗口的功能。两者的基本思路是差不多的,差别更多的是在实现细节上。相对于MBProgressHUD来说,SVProgressHUD的实现有以下几点不同:
SVProgressHUD类对外提供的都是类方法,包括显示、隐藏、和视图属性设置都是使用类方法来操作。其内部实现为一个单例对象,类方法实际是针对这个单例对象来操作的。
SVProgressHUD主要包含三部分:loading视图、提示文本框和背景框,没有详情文本框。
SVProgressHUD默认提供了正确、错误和信息三种状态视图(与loading视图同一位置,根据需要来设置)。当然MBProgressHUD中,也可以自定义视图(customView)来显示相应的状态视图。
SVProgressHUD为我们提供了更多的交互操作,包括点击事件、显示事件及隐藏事件。不过这些都是通过通知的形式向外发送,所以我们需要自己去监听这些事件。
SVProgressHUD中一些loading动画是以Layer动画的形式来实现的。
SVProgressHUD的实现细节还未详细去看,有兴趣的读者可以去研究一下。这两个HUD类库各有优点,大家在使用时,可根据自己的需要和喜好来选择。
总体来说,MBProgressHUD的代码相对朴实,简单易懂,没有什么花哨难懂的东西。就技术点而言,也没有太多复杂的技术,都是我们常用的一些东西。就使用而言,也是挺方便的,参考一下github上的使用指南就能很快上手
阅读(...) 评论()Pages: 1/2
主题 : MBProgressHUD使用时怎么改变旋转时的背景色,半透明的黑色好难看啊
级别: 侠客
可可豆: 367 CB
威望: 367 点
在线时间: 447(时)
发自: Web Page
来源于&&分类
MBProgressHUD使用时怎么改变旋转时的背景色,半透明的黑色好难看啊&&&
MBProgressHUD使用时怎么改变旋转时的背景色,半透明的黑色好难看啊
级别: 侠客
UID: 458460
可可豆: 876 CB
威望: 557 点
在线时间: 597(时)
发自: Web Page
Hud.color = [UIColor redColor];
级别: 侠客
UID: 458460
可可豆: 876 CB
威望: 557 点
在线时间: 597(时)
发自: Web Page
多看看头文件。。。
级别: 骑士
UID: 408527
可可豆: 555 CB
威望: 466 点
在线时间: 461(时)
发自: Web Page
回 2楼(liuchaoqian) 的帖子
貌似没用啊,必须要在.m文件里改,我当时就是在里面改的颜色和透明度
生活艰辛,但不低头。http://blog.csdn.net/codingfire
级别: 骑士
UID: 361236
可可豆: 329 CB
威望: 312 点
在线时间: 1115(时)
发自: Web Page
一楼正解:&&&&MBProgressHUD *hud=[MBProgressHUD showHUDAddedTo:self.view animated:YES];&&&&hud.mode=MBProgressHUDModeCustomV&&&&hud.color = [UIColor blueColor];&&&&hud.alpha = 0.8;&&&&hud.customView=contentL&&&&[hud hide:YES afterDelay:2.0];
级别: 侠客
UID: 458460
可可豆: 876 CB
威望: 557 点
在线时间: 597(时)
发自: Web Page
回 3楼(一字) 的帖子
额,我亲自测的。。。没用我会说?
级别: 骑士
UID: 408527
可可豆: 555 CB
威望: 466 点
在线时间: 461(时)
发自: Web Page
回 5楼(liuchaoqian) 的帖子
我也亲测了啊,要不然我也不会胡扯啊
生活艰辛,但不低头。http://blog.csdn.net/codingfire
级别: 侠客
UID: 458460
可可豆: 876 CB
威望: 557 点
在线时间: 597(时)
发自: Web Page
回 6楼(一字) 的帖子
我就纳闷了,你不在.m文件修改,难道你想在.h文件修改?自己看看4楼回复。
级别: 骑士
UID: 408527
可可豆: 555 CB
威望: 466 点
在线时间: 461(时)
发自: Web Page
回 5楼(liuchaoqian) 的帖子
哎呀,我错了,调错方法了。不过在第三方库里改下会方便点,要不然每次都要调那个方法也不是很好。&&&&&&&&&&&&&&&&&&&&
生活艰辛,但不低头。http://blog.csdn.net/codingfire
级别: 骑士
UID: 408527
可可豆: 555 CB
威望: 466 点
在线时间: 461(时)
发自: Web Page
回 7楼(liuchaoqian) 的帖子
额,刚开始说错还有点小小愧疚,看到你那句话瞬间无语,在第三方.m修改,呵呵哒,懒得鸟你。
生活艰辛,但不低头。http://blog.csdn.net/codingfire
Pages: 1/2
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版4129人阅读
转载自:&http://blog.csdn.net/qjlhlh/article/details/8127436
和gitHub上的Demo其实差不多,就是小整理了下,当备忘,想做复杂的效果可以参考MBProgressHUD在gitHub上的DEMO,写得也很清楚明了。
先下载MBProgressHUD.h和.m文件,拖入工程。地址:
以下是代码:(先在.h文件里定义 MBProgressHUD *HUD;)
代理方法:
用起来还是很easy的。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1881018次
积分:20369
积分:20369
排名:第292名
原创:411篇
转载:595篇
评论:95条
(3)(2)(1)(2)(2)(6)(4)(3)(4)(12)(4)(17)(9)(5)(11)(7)(22)(3)(12)(38)(32)(20)(5)(17)(35)(10)(24)(15)(8)(28)(13)(11)(28)(26)(20)(43)(55)(13)(14)(25)(12)(19)(37)(64)(29)(31)(7)(30)(12)(45)(19)(17)(23)(8)(11)(36)Pages: 1/2
主题 : MBProgressHUD能不能改变菊花的大小,怎么改变?
级别: 新手上路
UID: 301185
可可豆: 66 CB
威望: 56 点
在线时间: 482(时)
发自: Web Page
来源于&&分类
MBProgressHUD能不能改变菊花的大小,怎么改变?&&&
MBProgressHUD能不能改变菊花的大小,怎么改变?求解
新手IOS Developer,正在茁壮成长中,嘻嘻。。。。
级别: 新手上路
UID: 301185
可可豆: 66 CB
威望: 56 点
在线时间: 482(时)
发自: Web Page
回 楼主(lx) 的帖子
有大神知道么
新手IOS Developer,正在茁壮成长中,嘻嘻。。。。
级别: 侠客
UID: 275321
可可豆: 426 CB
威望: 250 点
在线时间: 641(时)
发自: Web Page
往里找啊。 找见控制的frame 就好了。 。&&总之是可以改得。
级别: 新手上路
UID: 301185
可可豆: 66 CB
威望: 56 点
在线时间: 482(时)
发自: Web Page
回 2楼(soleapp) 的帖子
你的意思是改源码了?
新手IOS Developer,正在茁壮成长中,嘻嘻。。。。
级别: 侠客
UID: 275321
可可豆: 426 CB
威望: 250 点
在线时间: 641(时)
发自: Web Page
改源码有什么 ,这不家常便饭么。。 哪有那么多找来就完全适用的东西啊。
级别: 新手上路
可可豆: 4 CB
威望: 4 点
在线时间: 24(时)
发自: Web Page
楼主说的菊花是那个白色的圈???UIActivityIndicatorView 修改 style
级别: 新手上路
可可豆: 18 CB
威望: 18 点
在线时间: 270(时)
发自: Web Page
&&&&&&&&&&
级别: 骑士
UID: 302426
可可豆: 471 CB
威望: 475 点
在线时间: 434(时)
发自: Web Page
系统自带的选定了style就不能通过改变frame改变大小了,只能改变位置。大小可以通过改变style选择(有两种大小)typedef NS_ENUM(NSInteger, UIActivityIndicatorViewStyle) {&&&&UIActivityIndicatorViewStyleWhiteLarge,&&&&UIActivityIndicatorViewStyleWhite,&&&&UIActivityIndicatorViewStyleGray,};除系统大小之外就只能自定义,那样大小就随便控制了。
世上无难事,只怕有心人。
级别: 新手上路
可可豆: 18 CB
威望: 18 点
在线时间: 270(时)
发自: Web Page
级别: 新手上路
可可豆: 2 CB
威望: 2 点
在线时间: 388(时)
发自: Web Page
回 7楼(yutiandesan) 的帖子
如何改变MBProgressHud的位置。。
Pages: 1/2
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版

我要回帖

更多关于 什么情况才能打封闭针 的文章

 

随机推荐