IOS状态栏是什么地方? 它是IOS设备屏幕顶部显示信号以及电池的区域。状态栏默认的高度是20像素,状态栏在软件开发中有何作用?联网应用中可在自动帮用户下载数据时使用,推荐在状态栏中予以显示。状态栏可以通过程序来控制隐藏与显示,也可以在状态栏之上添加Loading的动画,让用户感觉目前正处于下载状态中。下面我们先学习最简单的一种,就是在状态栏之上添加下载的Loading动画。如下图所示,在屏幕顶部状态栏中,信号图标旁边已经出现动画Loading的标志,它目前正在一直转圈。另外,本篇文章适用于普通IOS软件开发与Three20软件开发。
动画显示与隐藏的代码很简单,如下所示:
1 2 3 4 5 6 |
//开启状态栏动画 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; //关闭状态栏动画 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; |
这样的动画确实有点局限,不能修改动画的位置,我们可以将整个状态栏利用起来。写一个新视图覆盖至原有状态栏视图之上,在新视图中写入需要的东西。在学习它之前我们先学习如何隐藏与显示状态栏。
状态栏显示与隐藏的代码很简单,如下所示:
1 2 3 4 5 6 7 |
//隐藏状态栏 [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:YES]; //显示状态栏 [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:YES]; |
setStatusBarHidden :表示状态栏显示与隐藏。
withAnimation:表示是否播放显示与隐藏的过渡动画。
别高兴的太早,它仅仅只是隐藏状态栏,所以屏幕顶部还是会空留20像素的白条,为了让显示上更佳彻底,需要继续重新设定整个窗口的显示区域以及标题栏的位置:
1 2 3 4 5 6 7 8 |
//隐藏状态栏 [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:YES]; //重新设定窗口的显示区域 [[UIApplication sharedApplication].keyWindow setFrame:CGRectMake(0, 0, 320, 480)]; //重新设定标题栏显示的位置 [self.navigationController.navigationBar setFrame:CGRectMake(0, 0, 320, 44)]; |
如下图所示,状态条已经完全去掉,包括顶部的白条,是不是很神奇呢?
下面学习本文的重点内容,重写状态栏内容。如下图所示,状态栏顶部已经写入读取进度的百分比,为了让效果更佳好,在状态栏顶部将绘制进度条以及下载进度的百分比。在状态栏左侧将绘制读取动画,一个圆圈不停的转啊转啊的。嘎嘎~
下面开始详细的代码介绍。
ViewController.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#import <Three20/Three20.h> @interface ViewController : TTViewController { //下载进度显示视图 UITextView*textView; //状态条顶部Loading动画视图 UIActivityIndicatorView *activity; //计时器 NSTimer *timer; //应用程序的句柄 UIApplication *app; //计数 int timeCount; } @end |
ViewController.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
#import "ViewController.h" @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //设置标题栏文字 self.title =@"雨松MOMO软件开发"; //设置视图背景显示颜色 [self.view setBackgroundColor:[UIColor blackColor]]; //创建图片视图 TTImageView *imageview = [[[TTImageView alloc] initWithFrame: CGRectMake(100, 50, 120, 120)] autorelease]; //设置图片视图显示的图片资源 imageview.defaultImage = TTIMAGE(@"bundle://0.jpg"); //将图片视图加入整个视图当中 [self.view addSubview:imageview]; //按钮的文字信息 NSArray *titles = [[NSArray alloc] initWithObjects: @"隐藏状态栏", @"显示状态栏", @"更新状态栏", nil]; for (int i =0; i < [titles count]; i++) { //创建普通按钮 UIButton *button = [UIButton buttonWithType:1]; //设置按钮位置 button.frame = CGRectMake(0, 200 + i * 40, 320, 30); //设置按钮现实文字 [button setTitle:[titles objectAtIndex:i] forState:UIControlStateNormal]; //设置按钮标记 button.tag = i; //设置按钮点击后 绑定响应方法 [button addTarget:self action:@selector(ButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; //将按钮添加入视图中 [self.view addSubview: button]; } //得到应用程序的句柄 app = [UIApplication sharedApplication]; } -(void)ButtonPressed:(id)buttonID { //获取点击的按钮 UIButton *button = (UIButton *)buttonID; switch (button.tag) { case 0: //注解1 [app setStatusBarHidden:YES withAnimation:YES]; [app.keyWindow setWindowLevel:UIWindowLevelStatusBar]; [app.keyWindow setFrame:CGRectMake(0, 0, 320, 480)]; break; case 1: //注解2 [app setStatusBarHidden:NO withAnimation:YES]; [app.keyWindow setWindowLevel:UIWindowLevelStatusBar]; [app.keyWindow setFrame:CGRectMake(0, 20, 320, 460)]; break; case 2: //注解3 [app setStatusBarHidden:NO withAnimation:YES]; [app.keyWindow setWindowLevel:UIWindowLevelStatusBar]; [app.keyWindow setFrame:CGRectMake(0, 20, 320, 460)]; [self performSelector:@selector(startUpdate) withObject:nil afterDelay:0.4]; break; } //注解4 [self.navigationController.navigationBar setFrame:CGRectMake(0, 0, 320, 44)]; } - (void)dealloc { //释放 TT_RELEASE_SAFELY(textView); TT_RELEASE_SAFELY(activity); TT_RELEASE_SAFELY(timer); TT_RELEASE_SAFELY(app); [super dealloc]; } - (void) startUpdate { if(timer == nil) { //顶部文本视图 textView = [[UITextView alloc] initWithFrame:CGRectMake(0, -25, 320, 25)]; [textView setBackgroundColor:[UIColor blackColor]]; [textView setText:@"开始更新"]; [textView setTextColor:[UIColor whiteColor]]; [textView setTextAlignment:UITextAlignmentCenter]; [textView setFont:[UIFont systemFontOfSize:15]]; [app.keyWindow addSubview:textView]; //注解5 [UIView beginAnimations:@"anim1" context:nil]; [UIView setAnimationDuration:1.0]; textView.alpha = 0.0f; textView.alpha = 1.0f; [UIView commitAnimations]; [textView release]; //注解6 timer = [NSTimer scheduledTimerWithTimeInterval: 0.1 target: self selector: @selector(handleTimer:) userInfo: nil repeats: YES]; //开始播放loading动画 [self addLoading]; } } - (void) handleTimer: (NSTimer *) t { //开始计数,没进该方法一次++ timeCount++; //计数器小于100表示未下载完毕 if(timeCount <=100) { //绘制显示百分比 NSString *text = [NSString stringWithFormat:@"读取进度百分之:%d ",timeCount]; [textView setText:text]; }else { //计数器大于100表示下载完毕 [textView setText:@"读取完毕"]; timeCount = 0; //删除时间计时器 [self removeTimer]; //删除读取动画 [self removeLoading]; //注解7 [UIView beginAnimations:@"anim" context:nil]; [UIView setAnimationDuration:1.0]; textView.alpha= 1.0f; textView.alpha = 0.0f; [UIView commitAnimations]; } } - (void)addLoading { //创建Loading动画视图 activity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; //设置动画视图的风格,这里设定它位白色 activity.activityIndicatorViewStyle=UIActivityIndicatorViewStyleWhite; //设置它显示的区域 activity.frame = CGRectMake(0, -18, 20, 18); //将视图加入窗口中 [app.keyWindow addSubview:activity]; //开始播放动画 [activity startAnimating]; //释放 [activity release]; } -(void)removeLoading { //结束动画 [activity stopAnimating]; //删除动画视图 [activity removeFromSuperview]; } -(void)removeTimer { //停止时间计时器 TT_INVALIDATE_TIMER(timer); //等价于上面的方法 // //停止时间计时器 // [timer invalidate]; // //让它等于nil // timer = nil; } @end |
注解1:setStatusBarHidden:YES设定状态栏的隐藏,隐藏状态栏后,为了让下方原有的视图自动向上移动,那么就需要重新设定窗口的等级与显示区域。使用setWindowLevel方法可设定窗口的等级,窗口等级可分为三种:普通窗口,警告窗口,状态栏窗口,所以这里我们设定窗口等级为UIWindowLevelStatusBar(状态栏窗口)。窗口等级设定完毕后紧接着需要重新设定窗口的显示区域,重新设定窗口的显示区域为CGRect(0,0,320,480),表示新的窗口将完整填充整个手机屏幕。
注解2:状态栏的显示与状态栏的隐藏是一个道理,setStatusBarHidden:NO 设置状态栏可见,继续设定窗口的等级与显示区域。因为状态栏的高度为20,所以现在设定窗口的显示区域为CGRect(0,20,320,460),可保持视不包含状态栏的20像素高度,视图将填充下方整个屏幕。
注解3:在这里我们需要将新的视图覆盖至状态栏之上,首先是隐藏状态栏,隐藏时由于开启了隐藏状态栏的动画,所以延迟0.4毫秒等状态按彻底隐藏后在将新的视图覆盖至状态栏之上。使用performSelector方法,参数1表示延迟一段时间后执行的方法,参数2表示附带一个对象,参数3表示延迟的时间。这里是延迟0.4毫秒后执行startUpdate方法,下载属于以及更新视图都写在该方法中。
注解4:重新设定标题栏的位置,这个一定要设定,否则由于修改窗口的显示区域后标题栏显示上会出现偏差。
注解5:实现视图切换淡入淡出的效果,beginAnimations方法表示即将开始播放一段动画,setAnimationDuration方法表示设定动画播放的长度,textView.alpha表示设定视图的透明度,这里设定了2个透明度,0.0表示完全透明,1.0表示完全不透明,当然还可继续设定更多的视图变化,这段动画的含义是在1秒内现实视图从完全透明到完全不透明。最后执行[UIView commitAnimations]方法才是真正的开始播放动画,请大家记住beginAnimations 与commitAnimations两个方法必需成对儿出现,视图的任何变化都需要写在两个方法之间。
注解6:NSTimer表示时间计数器,它的原理就是在程序中新开一个子线程,并且子线程将每隔一段时间执行一次。本节我们使用它模拟用户下载数据的时间。这段代码表示程序将每隔0.1秒执行一次handleTimer方法,在handleTimer方法中去更新状态栏视图显示的文字,下载百分比。数据下载完毕后关闭视图,播放淡入淡出动画并且恢复原有状态栏。
最后在说说Three20中3个比较常用释放对象的宏定义:
1 2 3 4 5 6 7 |
#define TT_RELEASE_SAFELY(__POINTER) { [__POINTER release]; __POINTER = nil; } #define TT_INVALIDATE_TIMER(__TIMER) { [__TIMER invalidate]; __TIMER = nil; } // Release a CoreFoundation object safely. #define TT_RELEASE_CF_SAFELY(__REF) { if (nil != (__REF)) { CFRelease(__REF); __REF = nil; } } |
TT_RELEASE_SAFELY() :表示释放对象,并且将该对象赋值为nil。
TT_INVALIDATE_TIMER():停止时间计数器,并且将该计数器赋值为nil。
TT_RELEASE_CF_SAFELY:检测对象是否为nil,如果不为nil释放对象,最后赋值为nil。
最后欢迎各位盆友可以和MOMO一起讨论Three20软件开发,如果你觉得看得不清楚,MOMO附带上本章的源码下载,希望大家可以一起学习 哈哈~。哇咔咔~ MOMO愿和 大家好好学习,大家一起进步哈~!!!
- 本文固定链接: https://www.xuanyusong.com/archives/652
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
雨松加油