从UI布局到渲染-IOS

UI布局

界面布局常见的几种方式

  1. xib布局;
  2. storyboard布局;
  3. 纯代码布局--frame;
  4. 纯代码布局--Autolayout; 

xib布局

·  xib文件实际也是一个xml文件,也就是xml的可视化文件,解析xml节点,在通过runtime动态转换。

·  xib布局也分为两个阶段,一个是iphone6之前的小屏布局,以width:320px的横向座标为基础的autoresizing布局,一个是iphone6之后的Autolayout布局。

·  由于宽度限制在320px,所以除了高度,没有其他适配问题,布局较为简单,主要是以frame和autoresizing的结合。

·  自动布局的出现,使得界面布局不在局限于frame等比例适配机制,可以通过子视图于父视图直接的约束,或者是同级视图直接的约束来实现相对布局,灵活性更强。

storyboard布局

·  storyboard是建立在xib的基础上,可以把整个APP的交互用一个或者多个模块的storyboard拼接起来,显得更加直观,优点是快捷、直观,缺点是:耦合性较强、布局改动不灵活。

纯代码布局--frame

·  frame布局顾名思义,主要是以座标计算的形式来实现视图的布局,一般都做法是define设定一个屏幕scale比例值,对标750px的2倍屏宽度,从而计算出视图的frame(x, y, width, height)

纯代码布局--Autolayout

·  官方提供的Autolayout-API,主要是通过生成多个NSLayoutConstraint的集合,赋予其对应的View,来实现对View的约束(注意:View必须开启Autolayout属性且superView已经addSubview该View)。缺点:使用官方提供的API实现Autolayout代码会比较臃肿。

·  使用Masonry实现Autolayout布局,Masonry的API是使用链式编程的形式,简单易懂;相对官方提供的API,使用便捷,可读性较强。

纯代码布局--frame与Autolayout的对比

·  随着iphone的更新换代,市面上的iphone手机屏幕尺寸各式各样,如果APP不实现横竖屏切换,frame布局和Autolayout都是可以实现基本的UI效果;

·  frame布局相对传统一些,需要根据参照屏幕(6s尺寸)来实现比例缩放,计算起来会比较麻烦;autoLayout则相对流行一些,只要确保约束成立,就可以实现布局的定位,特别是搭配Masonry的使用,是现在比较通用的一种UI布局方式;

·  在动画实现上,frame布局和AutoLayout布局也是不一样的,前者是通过设置frame、锚点、position等位置尺寸属性来实现动画效果,后者则是通过修改约束来实现动画效果;

当然,两者也是可以一起使用的,具体也可以根据UI效果来做选择。

UI渲染

View的构成与层级关系

·  每个View都包含一个Layer,向一个View添加subView,也类似把subView的layer添加到View中,UIView还提供了绘图API:drawRect,可以在该方法中获取图形上下文,并实现图形的绘制,调用setNeedsDisplay刷新绘制;

·  添加到View的subView会在mainRunloop触发后进行绘制,并回调layoutSubviews方法,subView布局发生变化时,也是在mainRunloop触发后进行绘制,并回调layoutSubviews方法,layoutSubviews方法只有在多个操作在不同mainRunloop的触发时间段才会多次回调。

备注:图层的嵌套越多,加载速度越慢,过度嵌套会影响整个页面的流畅性。特别是比较复杂的图文混排list,快速地滑动会出现明显的顿挫感,解决方案是把结构复杂的多个图层通过图形上下文的形式转化为单图层渲染。

View的渲染

·  上面提到View的本质layer,每个layer都有个content这个content指向的是一块缓存又名baking store;Objective-c提供了Core Animation的渲染内核,底层是由OpenGL实现GPU渲染,流程大致如下:

  1. 初始化用于绘制的上下文EAGLContext;
  2. 创建帧缓冲区和渲染缓冲区,设置画布的宽高;
  3. 添加附件,比如颜色附件或者深度附件;
  4. 切换到帧缓冲区,在帧缓冲中进行绘制;
  5. 切换到屏幕缓冲区,读取帧缓冲中的信息;
  6. 绘制到屏幕上,在容器dealloc时删除缓冲区。

GPU的离屏渲染

On-Screen Rendering:当前屏幕渲染,指的是GPU的渲染操作在当前用于显示的屏幕缓冲区进行。

Off-Screen Rendering:离屏渲染,指的是GPU在当前屏幕缓冲区外新开辟一个缓冲区进行渲染操作。

·  离屏渲染主要开销:创建新的缓冲区、屏幕缓冲区到离屏缓冲区的来回切换。

·  IOS中主要是由于layer的某些属性设置导致的离屏渲染,常见的有遮罩(mask)、裁切(clip)、透明(opaque)、阴影(shadow)、栅格化(rasterize)、圆角(cornerRadius),离屏渲染会让APP的交互变得不流畅(如:比较复杂的图文混排list),所以应该尽量避免使用,采用其他方式来实现。

渲染性能优化

·  使用FaceBook的AsyncDisplayKit来写复杂的界面,能够获得异步绘制,预先加载等诸多好处。

·  YYKit图文混排引擎,大多数性能要求较高的界面就是图文混排,比如微博Feed,微信朋友圈等界面。

·  异步绘制,把复杂的界面,放到后台线程里绘制成一个bitmap,然后再显示。虽然有些延迟,不过换来的却是平滑的界面。

·  尽量使用CALayer,因为Layer是一个轻量级的视图结构,它不接受通知,不接受触摸,不在响应链。所以,相对于UIView来说,它的性能较好。并且CALayer及其子类是可以使用GPU渲染的,能够硬件加速。

·  预加载与缓存,对于复杂的TableView,可以对Cell视图的各个控件的大小,位置后台进行预计算,并且缓存起来。这样保证在heightForRow和cellForRow中不进行大量的计算。

·  图片的处理,尽量使用成熟的库,比如SDWebImage等,能够在后台进行图片解码,减少CPU的使用。尽量不要变形图片,保证图片与view尺寸一致。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章