学习笔记:iOS自动布局

学习笔记:iOS自动布局

Autolayout

1 布局实现

  • 约束&参照
    约束就是对控件的大小或者位置进行约束,参照就是以某个控件的位置进行约束,其实两者没有明确的分别,它们都可以对控件的位置尺寸起到作用。
  • 位置&尺寸
    而所有控件,都逃不开位置尺寸
  • 添加约束应遵循的规则
    – 对于两个同层级view之间的约束关系,添加到它们的父view上
    – 对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
    – 对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上

2 自动布局过程

2.1 步骤与方法

  • updating constraints(测量阶段)
    从下向上(from subview to super view),为下一步layout准备信息。
    – setNeedUpdateConstraints:调用可出发此步,constraints发生改变时也会触发此步
    – updateConstraintsIfNeeded: 在需要时(布局发生改变),自己通知Auto layout
    – updateConstraints:自定义view时,可通过重写此方法,添加相应的约束
  • layout(布局阶段)
    从上向下(from super view to subview),此步主要应用上一步的信息去设置view的center和bounds。
    – setNeedsLayout:通过调用触发此步骤,但不会立即更新
    – layoutIfNeeded:系统立即的更新layout
    – layoutSubViews:自定义view时,可重写该方法,获得更多效果
  • display(渲染/展示阶段)
    把view渲染到屏幕上,它与你是否使用Auto layout无关,其操作是从上向下(from super view to subview)
    – setNeedsDisplay:调用此方法触发

2.2 关系与顺序

  • 关系:
    display依赖layout,而layout依赖updating constraints。
    因为每一个方法对前一步有依赖,因此当有任何layout没有被处理的时候,一个display可能会触发layout,同理,当constraint system更新改变的时候,layout可能会触发updating constraints。
    而这个过程也不是单向的,layout过程中可能改变constraints,再一次触发updating constraints,进行新一轮layout过程。
  • 顺序:
    updating constraints->layout->display (非单向)

3 优先级

在Autolayout中每个约束都有一个优先级,优先级的范围是1 ~ 1000,默认创建的约束优先级是最高的1000。
设置优先级是为了在有多个约束的情况下,避免约束冲突的问题。有时候约束需要动态改变,也可以通过设置优先级解决冲突。
如删除一个button后要保持其他约束关系的情况:
设置约束的优先级
只有在优先级更高的约束失效之后,优先级低的备用的约束才会生效。
效果如图

几种布局方式对比

1 Frame

Frame的布局方式就是纯靠坐标布局,在灵活性上比较好,但大量数字让代码难以维护,但对比而言,在计算每个视图的Frame时需要在运行时进行大量计算,所以比较影响性能。
如果用了AutoLayout自动布局,那么我们在ViewDidLoad和ViewWillLayoutSubviews中修改Frame均不能生效,因为ViewWillLayoutSubviews这个方法在ViewDidLoad之后调用,也就是说frame生效之后接着就被autoLayout给重新布局了。所以要更改frame就要在ViewDidLayoutSubviews中更改。

2 Autoresizing

Autoresizing通过四条表示距离父视图上下左右边约束的线两条表示此视图的高度与宽度是否随着父视图的变化而按比例变化的线实现。
其局限性在于,所有的约束都是相对于父视图来设置的,也就是Autoresizing只能表现父与子的关系,而无法表达兄弟视图之间的关系。

3 xib

xib在使用上有些像storyboard,实际是一个小视图,将带有复杂性和有共性的问题单一处理掉,可以理解为:模板化(视图)
但xib与storyboard在工作的侧重点是完全不一样的。xib更喜欢去添加控件,而storyboard则是喜欢去添加控制器。

4 UIStackView

UIStackView 是 UIView 的子类,它不能用来呈现自身的内容,而是用来约束子控件的一个控件。UIStackView可以嵌套,可以在 StoryBoard 中使用,可以说是非常偷懒了。
但实际上,UIStackView只是提供了一个高效的接口用于平铺一行或一列的视图组合,省去布局嵌入其中的各个子视图的关系,不意味着不需要自动布局了,我们仍需设置一些约束来布局UIStackView本身。

5 Size Classes

sizeclass是对设备的一种抽象。它不再有尺寸、横屏和竖屏的概念,只有(Compact、Any,Regular)的概念,即把设备分为紧凑型、任意型、宽松型,免去了以前横屏一个xib,竖屏一个xib的麻烦。

性能与优化

1 性能

在使用 Auto Layout 进行布局时,可以指定一系列的约束,比如视图的高度、宽度等等。而其实,Autolayout仍要使用Frame布局,每一个约束反而都需要一定的计算,其效率远远低于单纯使用Frame,但相较于其他更高效的布局方式,其更具通用性。

2 卡顿产生原因

显示器多为从上到下扫描。
在最简单的情况下,帧缓冲区只有一个,这时帧缓冲区的读取和刷新都都会有比较大的效率问题。为了解决效率问题,显示系统通常会引入两个缓冲区,即双缓冲机制。在这种情况下,GPU 会预先渲染好一帧放入一个缓冲区内,让视频控制器读取,当下一帧渲染好后,GPU 会直接把视频控制器的指针指向第二个缓冲器。如此一来效率会有很大的提升。
双缓冲虽然能解决效率问题,但会引入一个新的问题。当视频控制器还未读取完成时,即屏幕内容刚显示一半时,GPU 将新的一帧内容提交到帧缓冲区并把两个缓冲区进行交换后,视频控制器就会把新的一帧数据的下半段显示到屏幕上,造成画面撕裂现象。所以就引入了垂直同步的机制。
iOS使用双缓存,并开启垂直同步。
这里写图片描述
在 VSync 信号到来后,系统图形服务会通过 CADisplayLink 等机制通知 App,App 主线程开始在 CPU 中计算显示内容,比如视图的创建、布局计算、图片解码、文本绘制等。随后 CPU 会将计算好的内容提交到 GPU 去,由 GPU 进行变换、合成、渲染。随后 GPU 会把渲染结果提交到帧缓冲区去,等待下一次 VSync 信号到来时显示到屏幕上。由于垂直同步的机制,如果在一个 VSync 时间内,CPU 或者 GPU 没有完成内容提交,则那一帧就会被丢弃,等待下一次机会再显示,而这时显示屏会保留之前的内容不变。这就是界面卡顿的原因。(以上,摘自https://www.cnblogs.com/ioriwellings/p/5011993.html

3 优化

使用Autolayout时,尽量提前计算好布局,在需要时一次性调整好对应属性,而不要多次、频繁的计算和调整这些属性。也可以使用更多高效的布局方式,或者把一些工作放到后台进行。

猜你喜欢

转载自blog.csdn.net/weixin_40477931/article/details/80156067