http://blog.csdn.net/hero82748274/article/details/47682047
最近一直在疑惑为什么有NavigationBar的情况, 我在view里面添加了一个UIlabel, 希望这个UIlable 的偏移的位置是离NavigationBar 底部 20 点即可。
我初始化使用的方法是 根据 获取状态栏的高度设计。然后计算他的高度
NSInteger height = self.navigationController.navigationBar.frame.size.height+20;
self.label = (CGRect) {0,height,200,20};
[self.view addSubView:self.label];
可是在我使用iOS 6的 真机调试发现,这个UILabel偏移得太厉害,我心想明明导航栏的高度就是44 ,再加上状态栏的20 就是 64,于是我的frame的高度值应该64+20(偏移值)就正确了。可是我真机调试发现效果相差太大, 无论我怎样理解都找不到问题原因。今天,我通过打印这个父类这个recursiveDescription 我一切的疑惑都解决到了。
(一些博客也提及到这个方面的问题)。IOS6和IOS7 改变导致了一些适配的问题。刚好我的手机一直只是IOS6系统。所以今天使用这个命令解决我之前的疑惑,也了解到组件树形层级关系。
注:这个方法是私有不公开 所以敲打要小心。
(lldb) po [self.view.superview recursiveDescription]
这里写图片描述
可以看到在UIView 有两个属性 一个是父类superview,一个是子类(subviews)。父类只有一个,子类可以有多个。
IOS7 以上模拟器调试下
我们再从日志里面查看到UIViewControllerWrapperView这个类干了什么事? 这个类里面frame 值是 (0 0; 375 667),再看 他的UIView 的frame (0 0; 375 667)。
在IOS 6真机 调试下
你可以看到一个另外一个不同的数据,显示到view其实位置在什么地方。 同样view 的坐标是 (0 ,0) 但是它的父类起始坐标就变成了(0,64)。这种情况是 导航栏+状态栏 ,而view的父类却在(0,64)的位置。
这里写图片描述
曾经有一回,我一直认为UIViewController 只有唯一个View 根对象存在,所以当我认定是这样,但是打印后,找到层级关系,发现这些细微的地方还是有存在的。有了这个方法,对调试真的起到很大作用。解析出为什么在IOS6 有导航栏下,view会在导航栏下面,原因就是他的父类起始发生变化(0,64),但我们平时操作的类都是使用view 进行,然而这个打印结果却让我们发生一些认识的改变
这里写图片描述
IOS7 以上下,UIViewControllerWrapperView 和UIView 的frame 是一样,是全屏的。所以他们开始坐标都是以(0,0)开始。
可以查阅这篇文章的打印结果得到不同情况下的frame值是如何改变。
self.view.frame
topLayoutGuide 和 bottomLayoutGuide 的使用
@property(nonatomic,readonly,retain) id<UILayoutSupport> topLayoutGuide NS_AVAILABLE_IOS(7_0);
@property(nonatomic,readonly,retain) id<UILayoutSupport> bottomLayoutGuide NS_AVAILABLE_IOS(7_0);
在ios7 里面有这样两个属性,在xcode 进行界面整理的时候,发现一个进行约束的时候可以兼容到IOS6 和IOS7的导航栏和状态栏问题操作。这个仅仅使用约束就能完成到。不需要编写任何代码。topLayoutGuide 属性提供了这个获取导航栏和状态栏的高度和。有了这个值就可以指定约束观察点。
需求很简单: 创建一个UIlabel 在导航栏偏移20个点,从上面输出打印日志可以看看 要完成这个操作 注意一点在IOS 6里面 父类 在导航栏下 刚好在 (0,64)的位置上,它的子类view则(0,0)。在IOS7里面,这个发生了变化。所以可以判断两个版本进行
-(void) viewWillLayoutSubviews
{
CGFloat height = 20;
if(IS_IOS7>6)
{
if ([self respondsToSelector:@selector(topLayoutGuide)])
{
height = self.topLayoutGuide.length +20(偏移20点完成上面的需求);
}
self.label.frame = (CGRect){0,height,200,200 };
}
}
在XIB的使用约束完成指定操作
在xib很方便拖放组件,包括在storyboard也是一样,很方便使用组件。有一个坑要注意是。我第一次使用这个storyboard 选定尺寸显示的时候,被这个玩意搞糊涂了。其实一开始做组件的时候,就要求选定这个尺寸观察。 4,4.7 3.5 也没问题,其实这个并没有太大关系。我们所需要做的工作对组件进行约束。 但是一旦想改这个尺寸,那么不好意思 你的约束和布局都全乱了。要重新来过,所以这个坑我还是遇上了。想想有了这个约束的机制,算出了一个相对位置,相对宽度,相对居中等。这些操作帮助我们做一些手机是屏幕适配工作了。