iOSUI布局IOS常用知识点整理

iOS导航栏

2016-05-21  本文已影响2014人  iOneWay

iOS7之后UI发生大变化。apple鼓励开发者进行全屏设计,这些并在UI的一些特性上也有所表现。

1.屏幕坐标起始点的变化
新建一个UIViewController并作为项目的RootController,在其View顶部添加一个UILabel,frame=(0,0,200,20)如图:

bar01.png

可以发现label与导航栏发生了重叠,由此可以推知:

iOS7后,坐标(0, 0)从整个屏幕的左上顶点开始计算。

当我们在该UIViewController外套一个UINavigationController后显示如图:


bar02.png

整个label被UINavigationBar覆盖了。

利用检测任意view的subviews的关系树一文中提供的工具方法打印keyWIndow的subViews树:如图

bar03.png

由上图可以知晓:

UINavigationBar的高度依旧是44px,
 其子View: UINavigationBarBackground高度为64px,origin.y=-20,
所以UINavigationBarBackground充当了状态栏和导航栏的背景。这也解释了通过修改UINavigationBar背景来改变导航栏背景的原理。

我们为UINavigationBar添加背景图片:如图

bar04.png

此时打印视图树,如图:

bar05.png

label视图出现在了导航栏下方,该效果由UIViewController的一个属性决定的:extendedLayoutIncludesOpaqueBars,这个属性指定了当Bar使用了不透明图片时,视图是否延伸至Bar所在区域,默认值时NO。如果把这个属性设置为YES,那么视图将会延伸至导航栏区域,即使我们把导航栏设置成了自定义背景。

1, 通过修改UINavigationBar的背景可以来修改状态栏背景
2, 当UIViewController. extendedLayoutIncludesOpaqueBars = NO 时,UINavigationBar添加背景图片后,UIViewController的视图的原点坐标为(0, 64), 下移了64px,并且高度缩减了64px。

通过设置UIViewController的属性:edgesForExtendedLayout来使label出现在导航栏下方:

self.edgesForExtendedLayout = UIExtendedEdgeNone;

如图:视图不会再延伸到导航栏后面了

bar06.png bar07.png

可以发现界面的变化,由此得出:

与为UINavigationBar添加背景图片效果相同
当视图中存在UIScrollView时

1,存在唯一一个UIScrollView或者其子类时:<注意唯一一个>

override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.whiteColor()

         /*****添加顶部UITableView*****/
        let table = UITableView.init(frame: self.view.bounds, style: .Plain);
        table.delegate = self;
        table.dataSource = self;
        self.view .addSubview(table)
        
        self.automaticallyAdjustsScrollViewInsets = true;
  
        /*****添加顶部UILabel*****/
        let label = UILabel.init(frame: CGRectMake(0, 0, 200, 20))
        label.text = "I am a label";
        self.view .addSubview(label)
    }

效果和视图树如图:

bar08.png
bar09.png

分析:
以上代码self.automaticallyAdjustsScrollViewInsets = true;,其中属性automaticallyAdjustsScrollViewInsets默认为true; 当其值为true时,如果视图里面存在唯一一个UIScrollView或其子类View,那么它会自动设置相应的内边距,但是不会重置scrollView的frame,这样可以让scroll占据整个视图,又不会让导航栏遮盖。

 override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.whiteColor()
        
        /*****添加顶部UILabel*****/
        let label = UILabel.init(frame: CGRectMake(0, 0, 200, 20))
        label.text = "I am a label";
        self.view .addSubview(label)
        
         /*****添加顶部Table*****/
        let table = UITableView.init(frame: self.view.bounds, style: .Plain);
        table.delegate = self;
        table.dataSource = self;
        self.view .addSubview(table)
        
        self.automaticallyAdjustsScrollViewInsets = true;
    }

本次是先添加label然后添加ScrollView,其效果和子视图如图:

bar11.png bar10.png

分析:代码self.automaticallyAdjustsScrollViewInsets = true;失效了。

此时我门可以使用属性:self.edgesForExtendedLayout = UIExtendedEdgeNone;,然后将ScrollView的高相应的缩减64px,来达到目的。

总结

iOS7之后apple鼓励开发者使用全屏布局,这样导致了视图的原点(0,0)为屏幕左上顶点,而不再是状态栏左下位置开始。

UIViewController的属性:

extendedLayoutIncludesOpaqueBars, 默认为false,
说明:这个属性指定了当Bar使用了不透明图片时,视图是否延伸至Bar所在区域,默认值时false。
所以我们如果自定义了导航栏的背景图片,那么视图会从导航栏以下开始,不会延伸到导航栏区域。
如果把这个属性设置为true,那么视图将会延伸至导航栏区域,即使我们把导航栏设置成了自定义背景

edgesForExtendedLayout, 默认为UIExtendedEdgeNone,
说明: 这个属性指定边缘要延伸的方向。
因为iOS7鼓励全屏布局,它的默认值很自然地是UIRectEdgeAll,四周边缘均延伸,就是说,如果即使视图中上有navigationBar,下有tabBar,那么视图仍会延伸覆盖到四周的区域。

automaticallyAdjustsScrollViewInsets, 默认为true
当设置为YES时(默认YES),如果视图里面存在唯一一个且为第一个加入视图的UIScrollView或其子类View,那么它会自动设置相应的内边距,这样可以让scroll占据整个视图,又不会让导航栏遮盖。若ScrollView不止一个或者不是第一个加入子视图则该属性将失效。

导航栏图片背景

添加背景图片

 self.navigationController?.navigationBar .setBackgroundImage(UIImage.init(imageLiteral: "barbar66.png"), forBarPosition: UIBarPosition.Top, barMetrics: UIBarMetrics.Default)

1,作为导航背景的图片:该图片是一个@2x图片:160*88

barbar88@2x.png

效果如图:

bar12.png

2,将图片换成barbar66@2x.png:160*66
效果如图:

bar13.png

3,将图片换成barbar100@2x.png:182*100
效果如图:

bar14.png

4,将图片换成barbar100@2x.png:182*128
效果如图:

bar15.png

5,将图片换成barbar228@2x.png:415*228
效果如图:

bar16.png

有以上结果可见:
假设图片高度为h,

  1. 当h<88 或者 88<h<128时,纵向横向平铺,覆盖导航栏
  2. 当h=88时,横向平铺,不覆盖导航栏
  3. 当h=128时,横向平铺,覆盖导航栏
  4. 当h>128时,纵向截取,横向平铺,覆盖导航栏

得到以上结论的前提是:所有图片是@2x图。关于一倍图,无论何种情况都是横向平铺纵向拉伸。

有关参数:BarPosition和barMetrics的确切作用目前还不十分清楚,等弄清楚了后续补充。

附上UINavigationBar的扩展,内涵:bar去下边线,bar透明,bar恢复默认状态等。见地址:http://pan.baidu.com/s/1i4UqdFJ

以上内容如有不足或错误欢迎指正留言。

上一篇下一篇

猜你喜欢

热点阅读