天天看点

导航控制器IOS上 关于状态栏的相关设置(UIStatusBar)

<p>方法一:
</p> <pre class="brush:cpp;toolbar: true; auto-links: false;"><code class="hljs css">第一步:
<span class="hljs-attr_selector">[self.collectionView registerNib:[UINib nibWithNibName:@"QGLShareBtnCell" bundle:nil]</span> <span class="hljs-tag">forCellWithReuseIdentifier</span>:<span class="hljs-at_rule">@<span class="hljs-keyword">"QGLShareBtnCell”];</span>
第二步:
QGLShareBtnCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@<span class="hljs-string">"QGLShareBtnCell"</span> forIndexPath:indexPath]</span>;</code>      

方法二:

    QGLIMGroupListCell *cell = (QGLIMGroupListCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell= (QGLIMGroupListCell *)[[[NSBundle  mainBundle]  loadNibNamed:@"QGLIMGroupListCell" owner:self options:nil]  lastObject];
    }                

- -!更为坑的是,居然忘记给xib设置identifier了。。。

-(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleDefault;}

如果viewController不是在 UINavgationController中,那么以上代码可以把状态栏文本颜色设置为白色,但是如果 viewController是添加到导航上的,你会发现上面代码达不到你想要的效果,状态栏文本颜色是黑色的!

这是为什么?

经过查找资料,才知道原来是这么一回事:

*UINavigationController不会将 preferredStatusBarStyle方法调用转给它的子视图,而是由它自己管理状态,而且它也应该那样做.因为UINavigationController 包含了它自己的状态栏

因此就算 UINavigationController中的viewController 实现了 preferredStatusBarStyle方法 也不会调用

那 UINavigationController是怎么决定 该返回 UIStatusBarStyleLightContent 还是 UIStatusBarStyleDefault的呢? 它是基于它的 UINavigationBar.barStyle属性.默认(UIBarStyleDefault)的是黑色文本的状态栏 而 UIBarStyleBlack是设置为白色文本的状态栏*

也就是说,如果viewController是在导航中的,想要改变状态栏文本颜色,那么需要通过代码:

//将status bar 文本颜色设置为白色
self.navigationController.navigationBar.barStyle = UIBarStyleBlack      
//将status bar 文本颜色设置为黑色 ,默认就是黑色
self.navigationController.navigationBar.barStyle = UIBarStyleDefault      

另外,如果viewController在导航中,还想通过 preferredStatusBarStyle 方法设置状态栏文本颜色,那就只能隐藏导航栏了:

//隐藏导航栏后 系统会调用 preferredStatusBarStyle 方法</span>
self.navigationController.navigationBarHidden = YES      

IOS上 关于状态栏的相关设置(UIStatusBar)

知识普及

ios上状态栏 就是指的最上面的20像素高的部分

状态栏分前后两部分,要分清这两个概念,后面会用到:

  • 前景部分:就是指的显示电池、时间等部分;
  • 背景部分:就是显示黑色或者图片的背景部分;

    如下图:前景部分为白色,背景部分为黑色

    导航控制器IOS上 关于状态栏的相关设置(UIStatusBar)

注意:这里只涉及到ios7以及更高版本,低版本下面的讲解可能无效。

设置statusBar的【前景部分】

简单来说,就是设置显示电池电量、时间、网络部分标示的颜色,这里只能设置两种颜色:

  • 默认的黑色(UIStatusBarStyleDefault)
  • 白色(UIStatusBarStyleLightContent)

可以设置的地方有两个:plist设置里面 和 程序代码里

1.plist设置statusBar

在plist里增加一行 UIStatusBarStyle(或者是“Status bar style”也可以),这里可以设置两个值,就是上面提到那两个UIStatusBarStyleDefault 和UIStatusBarStyleLightContent

这样在app启动的launch页显示的时候,statusBar的样式就是上面plist设置的风格。

2.程序代码里设置statusBar

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];  
           

或者

//相对于上面的接口,这个接口可以动画的改变statusBar的前景色  
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
           

不仅如此,ios还很贴心的在UIViewController也增加了几个接口,

目的是让状态栏根据当前显示的UIViewController来定制statusBar的前景部分。

  • - (UIStatusBarStyle)preferredStatusBarStyle;
  • - (UIViewController *)childViewControllerForStatusBarStyle;
  • - (void)setNeedsStatusBarAppearanceUpdate

- (UIStatusBarStyle)preferredStatusBarStyle:

在你自己的UIViewController里重写此方法,返回你需要的值(UIStatusBarStyleDefault 或者 UIStatusBarStyleLightContent);

注意:

  • 这里如果你只是简单的return一个固定的值,那么该UIViewController显示的时候,程序就会马上调用该方法,来改变statusBar的前景部分;
  • 如果在该UIViewController已经在显示在当前,你可能还要在当前页面不时的更改statusBar的前景色,那么,你首先需要调用下面的setNeedsStatusBarAppearanceUpdate方法(这个方法会通知系统去调用当前UIViewController的preferredStatusBarStyle方法), 这个和UIView的setNeedsDisplay原理差不多(调用UIView对象的setNeedsDisplay方法后,系统会在下次页面刷新时,调用重绘该view,系统最快能1秒刷新60次页面,具体要看程序设置)。

- (UIViewController *)childViewControllerForStatusBarStyle:

这个接口也很重要,默认返回值为nil。当我们调用setNeedsStatusBarAppearanceUpdate时,系统会调用application.window的rootViewController的preferredStatusBarStyle方法,我们的程序里一般都是用UINavigationController做root,如果是这种情况,那我们自己的UIViewController里的preferredStatusBarStyle根本不会被调用;

这种情况下childViewControllerForStatusBarStyle就派上用场了,

我们要子类化一个UINavigationController,在这个子类里面重写childViewControllerForStatusBarStyle方法,如下:

- (UIViewController *)childViewControllerForStatusBarStyle{
    return self.topViewController;
}
           

上面代码的意思就是说,不要调用我自己(就是UINavigationController)的preferredStatusBarStyle方法,而是去调用navigationController.topViewController的preferredStatusBarStyle方法,这样写的话,就能保证当前显示的UIViewController的preferredStatusBarStyle方法能影响statusBar的前景部分。

另外,有时我们的当前显示的UIViewController可能有多个childViewController,重写当前UIViewController的childViewControllerForStatusBarStyle方法,让childViewController的preferredStatusBarStyle生效(当前UIViewController的preferredStatusBarStyle就不会被调用了)。

简单来说,只要UIViewController重写的的childViewControllerForStatusBarStyle方法返回值不是nil,那么,UIViewController的preferredStatusBarStyle方法就不会被系统调用,系统会调用childViewControllerForStatusBarStyle方法返回的UIViewController的preferredStatusBarStyle方法。

- (void)setNeedsStatusBarAppearanceUpdate:

让系统去调用application.window的rootViewController的preferredStatusBarStyle方法,如果rootViewController的childViewControllerForStatusBarStyle返回值不为nil,则参考上面的讲解。

设置statusBar的【背景部分】

背景部分,简单来说,就是背景色;改变方法有两种:

系统提供的方法

navigationBar的setBarTintColor接口,用此接口可改变statusBar的背景色

注意:一旦你设置了navigationBar的- (void)setBackgroundImage:(UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics接口,那么上面的setBarTintColor接口就不能改变statusBar的背景色,statusBar的背景色就会变成纯黑色。

另辟蹊径

创建一个UIView,

设置该UIView的frame.size 和statusBar大小一样,

设置该UIView的frame.origin 为{0,-20},

设置该UIView的背景色为你希望的statusBar的颜色,

在navigationBar上addSubView该UIView即可。

refer:

Information Property List Key Reference: iOS Keys

iOS7中容易被忽视的新特性 - CocoaChina 苹果开发中文站

首先是无故事板模式下

一 创建一个导航控制器

1 创建一个viewcontrol   Test_OneViewController

@interface AppDelegate :UIResponder <UIApplicationDelegate>

{

    Test_OneViewController *test;

    UINavigationController *navigation;

}

@property (strong,nonatomic)UIWindow *window;

@property (strong,nonatomic)UINavigationController *navigation;

@end

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

    self.window = [[UIWindowalloc]initWithFrame:[[UIScreenmainScreen]bounds]];

    self.window.backgroundColor = [UIColorwhiteColor];

   test = [[Test_OneViewController   alloc]init];

   navigation = [[UINavigationController  alloc]initWithRootViewController:test];

    [self.window   addSubview:navigation.view];

    [self.windowmakeKeyAndVisible];

    returnYES;

}

///

// Uses a horizontal slide transition. Has no effect if the view controller is already in the stack.

//推送到下一个视图

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated; 

 // Returns the popped controller.

//返回上一个视图

- (UIViewController *)popViewControllerAnimated:(BOOL)animated;

// Pops view controllers until the one specified is on top. Returns the popped controllers.

返回一个指定的视图

- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated

 // Pops until there's only a single view controller left on the stack. Returns the popped controllers.

//返回根视图

- ( NSArray  *)popToRootViewControllerAnimated:( BOOL )animated;

///

这时候我们们创建了一个导航控制器!在首页上我们会看见一个导航栏

二 在导航控制器上我们添加两个按钮   UIBarButtonItem

.///  Test_OneViewController   //

通过  - (id)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action 函数创建了两个UIBarButtonItem

    self.title =@"导航控制器";  //导航标题

    UIBarButtonItem *rightButton = [[UIBarButtonItem   alloc]initWithTitle:@"push"style:UIBarButtonItemStyleDone target:self  action:@selector(pushAction)];

    self.navigationItem.rightBarButtonItem = rightButton;

    UIBarButtonItem *leftButton = [[UIBarButtonItem   alloc]initWithTitle:@"mode"style:UIBarButtonItemStyleDone  target:self  action:@selector(modeAction)];

    self.navigationItem.leftBarButtonItem = leftButton;

// mode 方式推送到一个视图 这种情况通常用来选取数据,调用系统通讯录 设置 等  需要手动写取消返回

//typedef NS_ENUM(NSInteger, UIModalTransitionStyle) {

  //  UIModalTransitionStyleCoverVertical = 0,

   // UIModalTransitionStyleFlipHorizontal,

    //UIModalTransitionStyleCrossDissolve,

-(void)modeAction

{

    ModeViewController *mode = [[ModeViewController  alloc]init];

    mode.modalTransitionStyle =UIModalTransitionStyleFlipHorizontal; //设置翻转动画效果  

    //mode.modalPresentationStyle = UIModalPresentationFormSheet; //显示外观动画

  [self  presentViewController:mode  animated:YES completion:nil];

}

//反回到上一个视图

-(void)dissMissModeAction

{

    [self   dismissViewControllerAnimated:YEScompletion:nil];

}

// push 常用的推送方式,推送成功后下个视图会出现back 返回按钮

-(void)pushAction

{

    PushViewController *push = [[PushViewControlleralloc]init];

    [self.navigationControllerpushViewController:pushanimated:YES ];

}

问题 一  但是现在发现 返回按钮是英文的  应该改成汉语

我们在 添加左右item 的地方添加个backButtonItem

在ios7中有可以取消字母提示 用系统的图标更简洁 只要把title 设置为空就ok了

   UIBarButtonItem *backButtonItem = [[UIBarButtonItemalloc]init];

    //backButtonItem.title = @"返回";

    backButtonItem.title = @"";

   self.navigationItem.backBarButtonItem = backButtonItem;

问题二  发现导航栏是透明的 并且不暂用像素

我们可以通过设置bool 值 来隐藏导航栏

我们可以设置 bool 值来改变 透明不透明

self.navigationController.navigationBar.translucent =NO;

问题 三 有时候我们在自定义导航栏时候不想显示系统的导航栏怎么办

 self.navigationController.navigationBarHidden =YES;

问题四      如何改变系统导航栏的颜色 和自定义标题

ios7 xcode5 环境下

UIColor *navigationBackColor = [UIColorcolorWithRed:82.0/255.0green:135.0/255.0blue:237.0/255.0alpha:1.0];

   // ios7 新增加的方法  在xcode 5 下 

  self.navigationController.navigationBar.barTintColor = navigationBackColor;

 // 这个方法可与改变字体的颜色

 self.navigationController.navigationBar.tintColor = navigationBackColor;

能改变字体的颜色

ios 6.1 xcode 4 环境下

UIColor *navigationBackColor = [UIColor colorWithRed:82.0/255.0 green:135.0/255.0 blue:237.0/255.0 alpha:1.0];

  self.navigationController.navigationBar.tintColor =navigationBackColor;

如何在ios6.1的 情况下需要自定义 title的

    UILabel *navigateTitleLabel = [[UILabelalloc]initWithFrame:CGRectMake(0,0,100,30)];

    navigateTitleLabel.font = [UIFontsystemFontOfSize:20.0];

    navigateTitleLabel.textColor = [UIColorblackColor];

    navigateTitleLabel.backgroundColor = [UIColorclearColor];

    navigateTitleLabel.textAlignment =NSTextAlignmentCenter;

    navigateTitleLabel.text = @"导航控制器";

    self.navigationItem.titleView = navigateTitleLabel;

// 用系统的item/

我么通过这个函数可以设置系统提供的Item

- (id)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(id)target action:(SEL)action;

typedefNS_ENUM(NSInteger, UIBarButtonSystemItem) {

    UIBarButtonSystemItemDone,

    UIBarButtonSystemItemCancel,

    UIBarButtonSystemItemEdit,  

    UIBarButtonSystemItemSave,  

    UIBarButtonSystemItemAdd,

    UIBarButtonSystemItemFlexibleSpace,

    UIBarButtonSystemItemFixedSpace,

    UIBarButtonSystemItemCompose,

    UIBarButtonSystemItemReply,

    UIBarButtonSystemItemAction,

    UIBarButtonSystemItemOrganize,

    UIBarButtonSystemItemBookmarks,

    UIBarButtonSystemItemSearch,

    UIBarButtonSystemItemRefresh,

    UIBarButtonSystemItemStop,

    UIBarButtonSystemItemCamera,

    UIBarButtonSystemItemTrash,

    UIBarButtonSystemItemPlay,

    UIBarButtonSystemItemPause,

    UIBarButtonSystemItemRewind,

    UIBarButtonSystemItemFastForward,

我们可以先把导航左边的的Item 改成 UIBarButtonSystemItemSearch 一个搜索的图形

    UIBarButtonItem *leftButton = [[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemSearchtarget:selfaction:@selector(modeAction)];

    self.navigationItem.leftBarButtonItem = leftButton;

问题五 通过图片 改变back 按钮 

// ITEM 添加图片/

- (id)initWithImage:(UIImage *)image landscapeImagePhone:(UIImage *)landscapeImagePhone style:(UIBarButtonItemStyle)style target:(id)target action:

我在back 所在的视图类添加一下代码 就把按钮替换成自己定义的风格图形的按钮了 同理当然可以改变push 的item

   UIImage *imge = [UIImageimageNamed:@"导航_返回.png"];

    UIBarButtonItem *leftButton = [[UIBarButtonItemalloc]initWithImage:imgestyle:UIBarButtonItemStyleDonetarget:selfaction:@selector(pushActions)];

    self.navigationItem.leftBarButtonItem = leftButton;

// 然后通过 [self.navigationController popViewControllerAnimated:YES]; 返回上一级视图

-(void)pushActions

{

    [self.navigationControllerpopViewControllerAnimated:YES];

}

问题 六 自定义一个导航栏按钮

- (id)initWithCustomView:(UIView *)customView;

我在返回按钮的视图里右边又加了一个返回按钮 但是通过自定义的方式

    UIButton * rightbtn = [UIButton  buttonWithType:UIButtonTypeCustom];

    rightbtn.frame =CGRectMake(8,10,25,20);

    [rightbtn setBackgroundImage:imge forState:UIControlStateNormal];

    UIBarButtonItem *  revealButtonItem = [[UIBarButtonItem  alloc]initWithCustomView:rightbtn];

    self.navigationItem.rightBarButtonItem = revealButtonItem;

我们发现api 提供的这个方法的参数是个view

如果加个button 不是很明显那么我们就添加个textfield 把 这样更直观

    UITextField *textfield = [[UITextFieldalloc]initWithFrame:CGRectMake(8,10,80,25)];

    textfield.placeholder =@"hello";

    textfield.backgroundColor = [UIColorwhiteColor];

    UIBarButtonItem *  revealButtonItem = [[UIBarButtonItemalloc]initWithCustomView:textfield];

    self.navigationItem.rightBarButtonItem = revealButtonItem;

    问题 七  在导航栏中间添加分段控件

  主要是通过这个函数   self.navigationItem.titleView = segment;

    NSArray *buttonName = [NSArrayarrayWithObjects:@"周杰伦",@"张学友",@"王大那",nil];

    UISegmentedControl *segment = [[UISegmentedControlalloc]initWithItems:buttonName];

    segment.momentary =YES;

    [segment addTarget:selfaction:@selector(segmengAction:)forControlEvents:UIControlEventEditingChanged];

    self.navigationItem.titleView = segment;

    问题八  导航右侧添加两个buttonItem

    UIBarButtonItem *oneButton = [[UIBarButtonItemalloc]initWithTitle:@"first"style:UIBarButtonItemStyleDone target:selfaction:@selector(oneButtonAction:)];

    UIBarButtonItem *twoButton = [[UIBarButtonItemalloc]initWithTitle:@"second"style:UIBarButtonItemStyleDone target:selfaction:@selector(twoButtonAction:)];

    NSArray *actionButtonItems = @[oneButton,   twoButton];

    self.navigationItem.rightBarButtonItems = actionButtonItems;

  问题九  添加导航栏背景图片

   [navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"导航背景.png"] forBarMetrics:UIBarMetricsDefault];

  问题十  知道系统返回按钮事件

   在返回按钮的上一级页面

          在 push 时指定delegate 

            [self.navigationControllerpushViewController:interestJobanimated:YES];

            self.navigationController.delegate =self;

            hideNavigationBar =NO;

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated

{

    if (hideNavigationBar) {

       // 返回事件

    }

    hideNavigationBar = YES;

}

问题十一 如何pop 回指定的页面

    [self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:([self.navigationController.viewControllerscount] -2)] animated:YES];

转载自

http://blog.csdn.net/lengshengren/article/details/16820803

继续阅读