1 问题
从iOS7开始,视图控制器会渗透到各种Bar下面,包括:NavigationBar、ToolBar、TabBar、StatusBar等;这些Bar会挤占视图的空间,在布局时就需要根据各种Bar所挤占的空间大小来计算控件的frame,本案例直接在上一个案例的基础上实现,根据上边栏和下边栏的高度对界面进行布局,如图1、图2所示:
2 方案
首先在上一个案例的基础上增加一个NavigationController和TabBarController,在界面的中间拖放一个Button控件,标题设置为“隐藏NavigationBar”,并将Button控件关联成TRViewController的私有方法hideNavigationBar。
然后在ViewController类中重写布局方法viewDidLayoutSubviews,在该方法中根据父视图的bounds和上下边栏的高度计算Button和Label的frame。
3 步骤
实现此案例需要按照如下步骤进行。
步骤一:创建项目,添加按钮控件
在上一个案例的基础上增加一个NavigationController和TabBarController,在界面的中间拖放一个Button控件,标题设置为“隐藏NavigationBar”,如图3所示:
然后将Button控件关联成ViewController的私有方法hideNavigationBar,该方法的功能是将导航栏隐藏或显示,代码如下所示:
- (IBAction)hideNavigationBar:(id)sender {
self.navigationController.navigationBarHidden = !self.navigationController.navigationBarHidden;
}
步骤二:重写布局方法viewDidLayoutSubviews,进行界面布局
在ViewController类中重写布局方法viewDidLayoutSubviews,在该方法中根据先通过属性self.topLayoutGuide.length和self.bottomLayoutGuide.length获取到上下边栏的高度,然后再通过父视图的bounds和上下边栏的高度计算出Button和Label的frame,代码如下所示:
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
CGFloat buttonWidth = (self.view.bounds.size.width - 20 - 20 - 10) * 0.5;
//从iOS7开始,可以随时知道VC的上面和下面被各种Bar占据了多少的空间
CGFloat top = self.topLayoutGuide.length;
CGRect frame =CGRectMake(20,top+40,buttonWidth,40);
self.button1.frame = frame;
frame.origin.x += buttonWidth + 10;
self.button2.frame = frame;
//下面的各种Bar(TabBar或ToolBar)占了VC多高的空间
CGFloat bottom = self.bottomLayoutGuide.length;
frame = self.label.frame;
frame = CGRectMake(self.view.bounds.size.width - 20 - frame.size.width , self.view.bounds.size.height - 10 - frame.size.height - bottom, frame.size.width, frame.size.height);
self.label.frame = frame;
frame = self.hideButton.frame;
frame.origin.x = self.view.bounds.size.width * 0.5 - frame.size.width * 0.5;
frame.origin.y = self.view.bounds.size.height * 0.5 - frame.size.height * 0.5;
self.hideButton.frame = frame;
}
4 完整代码
本案例中,ViewController.m文件中的完整代码如下所示:
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIButton *button1;
@property (weak, nonatomic) IBOutlet UIButton *button2;
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UIButton *hideButton;
- (IBAction)hideNavigationBar:(id)sender;
@end
@implementation ViewController
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
CGFloat buttonWidth = (self.view.bounds.size.width - 20 - 20 - 10) * 0.5;
//从iOS7开始,可以随时知道VC的上面和下面被各种Bar占据了多少的空间
CGFloat top = self.topLayoutGuide.length;
CGRect frame =CGRectMake(20,top+40,buttonWidth,40);
self.button1.frame = frame;
frame.origin.x += buttonWidth + 10;
self.button2.frame = frame;
//下面的各种Bar(TabBar或ToolBar)占了VC多高的空间
CGFloat bottom = self.bottomLayoutGuide.length;
frame = self.label.frame;
frame = CGRectMake(self.view.bounds.size.width - 20 - frame.size.width , self.view.bounds.size.height - 10 - frame.size.height - bottom, frame.size.width, frame.size.height);
self.label.frame = frame;
frame = self.hideButton.frame;
frame.origin.x = self.view.bounds.size.width * 0.5 - frame.size.width * 0.5;
frame.origin.y = self.view.bounds.size.height * 0.5 - frame.size.height * 0.5;
self.hideButton.frame = frame;
}
- (IBAction)hideNavigationBar:(id)sender {
self.navigationController.navigationBarHidden = !self.navigationController.navigationBarHidden;
}