手机
当前位置:查字典教程网 >编程开发 >IOS开发 >iOS开发:自定义状态栏代码详解
iOS开发:自定义状态栏代码详解
摘要:公司的开发的项目要求在状态栏上边加入程序下载的进度条,之前写的程序,由于是根据ipad的朝向来设置自定义的状态栏的frame,以及子视图的f...

公司的开发的项目要求在状态栏上边加入程序下载的进度条,之前写的程序,由于是根据ipad的朝向来设置自定义的状态栏的frame,以及子视图的 frame和transform,出现一些不太容易解决的bug。这两天正好项目不太紧,就好好学习一下这方面的知识,以下是我所总结的一点经验:

这里说明一下,Apple没有开放的状态栏的API,在ios 的官方文档没有提到修改Window Level的方式;

先看一下Window Level的可用的值包括:

1: typedef CGFloat UIWindowLevel;

2: const UIWindowLevel UIWindowLevelNormal; // 0.0

3: const UIWindowLevel UIWindowLevelAlert; // 2000.0

4: const UIWindowLevel UIWindowLevelStatusBar; // 1000.0

默认我们的UIView layer都是在UIWindowLevelNormal上,这也就是为什么系统弹出来的对话框在我们的视图之上,因为它的Window Level级别更高。

根据WindowLevel的原理我们也就知道,如果想在系统的状态栏上,添加自定义的状态栏,就需要比UIWindowLevelStatusBar的级别更高,接下来,用代码说明一下:

首先,先建一个Single View Application,名字自定义就可以了,

然后,新建一个类命名为: StatusBarOverlay 继承自UIWindow类,代码:

StatusBarOverlay.h文件

1: #import

2:

3: @interface StatusBarOverlay : UIWindow{

4: UIView *contentView;

5: UILabel *textLabel;

6: }

7:

8: @property (nonatomic, retain) UIView *contentView;

9:

10: @property (nonatomic, retain) UILabel *textLabel;

11:

12: @end

StatusBarOverlay.m文件

1: //

2: // StatusBarOverlay.m

3: // StatusBarDemo

4: //

5: // Created by jordy wang on 12-8-7.

6: // Copyright (c) 2012年 __MyCompanyName__. All rights reserved.

7: //

8:

9: #import "StatusBarOverlay.h"

10:

11: #define STATUS_BAR_ORIENTATION [UIApplication sharedApplication].statusBarOrientation

12: #define ROTATION_ANIMATION_DURATION [UIApplication sharedApplication].statusBarOrientationAnimationDuration

13:

14:

15: @interface StatusBarOverlay()

16:

17: - (void)initializeToDefaultState;

18: - (void)rotateStatusBarWithFrame:(NSValue *)frameValue;

19: - (void)setSubViewHFrame;

20: - (void)setSubViewVFrame;

21: @end

22:

23:

24: @implementation StatusBarOverlay

25: @synthesize contentView;

26: @synthesize textLabel;

27:

28: //重写init方法

29: - (id)init

30: {

31: self = [super initWithFrame:CGRectZero];

32: if (self) {

33: self.windowLevel = UIWindowLevelStatusBar + 1;

34: self.frame = [UIApplication sharedApplication].statusBarFrame;

35: [self setBackgroundColor:[UIColor orangeColor]];

36: [self setHidden:NO];

37:

38: //内容视图

39: UIView *_contentView = [[UIView alloc] initWithFrame:self.bounds];

40: self.contentView = _contentView;

41: [self.contentView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];

42: [self.contentView setBackgroundColor:[UIColor cyanColor]];

43: [self addSubview:self.contentView];

44: [_contentView release];

45:

46:

47: //添加textLabel

48: UILabel *_textLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 0, CGRectGetWidth(self.frame)-60, CGRectGetHeight(self.frame))];

49: self.textLabel = _textLabel;

50: [self.textLabel setBackgroundColor:[UIColor blueColor]];

51: [self.textLabel setFont:[UIFont systemFontOfSize:12]];

52: [self.textLabel setTextAlignment:UITextAlignmentCenter];

53: [self.textLabel setTextColor:[UIColor blackColor]];

54: [self.textLabel setText:@"自定义的状态栏 author by jordy"];

55: [self.contentView addSubview:self.textLabel];

56: [_textLabel release];

57:

58: //注册监听---当屏幕将要转动时,所出发的事件(用于操作本视图改变其frame)

59: [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willRotateScreenEvent:)

name:UIApplicationWillChangeStatusBarFrameNotification object:nil];

60: //初始化

61: [self initializeToDefaultState];

62: }

63:

64: return self;

65: }

66:

67:

68:

69:

70: //初始化为默认状态

71: - (void)initializeToDefaultState

72: {

73: //获取当前的状态栏位置

74: CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;

75: //设置当前视图的旋转, 根据当前设备的朝向

76: [self rotateStatusBarWithFrame:[NSValue valueWithCGRect:statusBarFrame]];

77:

78:

79:

80: }

81:

82:

83: //旋转屏幕

84: - (void)rotateStatusBarWithFrame:(NSValue *)frameValue

85: {

86: CGRect frame = [frameValue CGRectValue];

87: UIInterfaceOrientation orientation = STATUS_BAR_ORIENTATION;

88:

89: if (orientation == UIDeviceOrientationPortrait) {

90: self.transform = CGAffineTransformIdentity; //屏幕不旋转

91: [self setSubViewVFrame];

92: }else if (orientation == UIDeviceOrientationPortraitUpsideDown) {

93: self.transform = CGAffineTransformMakeRotation(M_PI); //屏幕旋转180度

94: [self setSubViewVFrame];

95: }else if (orientation == UIDeviceOrientationLandscapeRight) {

96: self.transform = CGAffineTransformMakeRotation((M_PI * (-90.0f) / 180.0f)); //屏幕旋转-90度

97: [self setSubViewHFrame];

98: }else if (orientation == UIDeviceOrientationLandscapeLeft){

99: self.transform = CGAffineTransformMakeRotation(M_PI * 90.0f / 180.0f); //屏幕旋转90度

100: [self setSubViewHFrame];

101: }

102:

103: self.frame = frame;

104: [self.contentView setFrame:self.bounds];

105: }

106:

107: //设置横屏的子视图的frame

108: - (void)setSubViewHFrame

109: {

110: self.textLabel.frame = CGRectMake(30, 0, 1024-60, 20);

111: }

112: //设置竖屏的子视图的frame

113: - (void)setSubViewVFrame

114: {

115: self.textLabel.frame = CGRectMake(30, 0, 748-60, 20);

116: }

117:

118: #pragma mark -

119: #pragma mark 响应屏幕即将旋转时的事件响应

120: - (void)willRotateScreenEvent:(NSNotification *)notification

121: {

122: NSValue *frameValue = [notification.userInfo valueForKey:UIApplicationStatusBarFrameUserInfoKey];

123: [self rotateStatusBarAnimatedWithFrame:frameValue];

124: }

125:

126: - (void)rotateStatusBarAnimatedWithFrame:(NSValue *)frameValue {

127: [UIView animateWithDuration:ROTATION_ANIMATION_DURATION animations:^{

128: self.alpha = 0;

129: } completion:^(BOOL finished) {

130: [self rotateStatusBarWithFrame:frameValue];

131: [UIView animateWithDuration:ROTATION_ANIMATION_DURATION animations:^{

132: self.alpha = 1;

133: }];

134: }];

135: }

136:

137: - (void)dealloc

138: {

139: [[NSNotificationCenter defaultCenter] removeObserver:self];

140: [textLabel release];

141: textLabel = nil;

142:

143: [contentView release];

144: contentView = nil;

145:

146: [super dealloc];

147: }

148:

149: @end

由于代码比较简单,并且我在上述代码里有相应的注释,这里需要说明一点的是,默认我们继承自UIWindow的StatusBarOverlay类是hidden状态,需要在初始化的时候设置它的hidden属性为NO,

在屏幕旋转过程中,自定义的状态栏与UIViewController之间的旋转是分离的,所以我们需要做一个隐藏的动画,在旋转过程前先隐藏自定义的状态栏,旋转结果后设置显示状态。

如果需要做一种动画,比方从底部下移显示一条信息,隔N秒后又自动收回的动画,直接设置自定义的视图的y坐标就可以了,默认y坐标设置是0。

最后, 使用它的方式也比较简单,只需要初始化,代码:

StatusBarOverlay *statusBarOverlay = [[StatusBarOverlay alloc] init];

由于我公司的需求是开机自动下载的功能,所以我在初始化的时候,是放在了AppDelegate中。

【iOS开发:自定义状态栏代码详解】相关文章:

iOS App开发中Masonry布局框架的基本用法解析

苹果iOS9发布:历代iOS亮点回顾

iOS 开发常用宏总结

iOS开发:Web应用简单本地化

iOS App开发中的UIStackView堆叠视图使用教程

Objective-C实现自定义的半透明导航

iOS开发之触摸事件

iOS开发之自定义UITextField的方法

iOS开发:strong、weak等详解

IOS开发:Unity3D根据动态的两个轨迹点绘制面详解

精品推荐
分类导航