1.Views
视图的功能:
- 布局和子视图管理
- 根据父视图指定一个默认的自动调整行为
- 管理子视图
- 可以重写子视图的大小和位置
- 可以将在自身坐标系中的points转为窗口中其他视图坐标系中的points
- 绘制和动画
- 在视图的矩形区域中绘制内容
- 一些属性可以被赋新值
- 事件处理
- 可以接收触摸事件
- 参与响应链
1.2 创建和配置视图对象
a)用代码创建视图
默认的初始化方法是initWithFrame:,可以设置初始化的大小和位置。
创建好视图之后,要把它添加到窗口或者另一个视图中才能显示。Adding and Removing Subviews
b)设置视图的属性
UIView类有一些属性来控制视图的外观和行为。
-
控制视图的透明度。
-
控制视图的大小和位置。
Center 和 frame控制视图相对于其父视图的位置;frame也可以设置大小;bounds定义自己视图坐标系上的可视区域;transform控制视图的移动和动画。The Relationship of the Frame, Bounds, and Center Properties
autoresizingMask,autoresizesSubviews
控制视图和子视图的自动调整大小。
autoresizingMask控制视图响应父视图的bounds的改变;autoresizesSubviews控制当前视图的子视图是否可以resize
contentMode,contentStretch,contentScaleFactor
控制视图内容的渲染行为。
Content Modes 和 Stretchable Views确定当视图宽度或者高度改变的时候内容如何变化;contentScaleFactor用在你要自定义视图在高分辨率下的绘制行为,Supporting High-Resolution Screens In Views。
gestureRecognizers,userInteractionEnabled,multipleTouchEnabled,exclusiveTouch
处理触摸事件
backgroundColor,subviews,drawRect:方法,layer,layerClass方法
管理视图中的具体内容
要自定义绘制行为,需要重写drawRect方法;要设置更高级的内容,可以直接使用layer;要指定一个和layer完全不一样的类型,需要重写layerClass方法。
c)标记视图以便于将来识别
用tag属性对每个视图对象标记一个整数,可以优化运行时的视图搜索,默认的tag值是0.
使用viewWithTag:方法来搜索被标记的视图,但是只能搜索当前视图的子视图。
1.3 创建和管理视图结构层次
a)添加、移除子视图
- 调用addSubview:方法将子视图添加到父视图的subviews列表的最后
- 调用
insertSubview(_:aboveSubview:)
将子视图插入到subviews的中间 - 重排subviews列表的顺序,使用bringSubviewToFront:、sendSubviewToBack:、exchangeSubviewAtIndex:withSubviewAtIndex:
- 删除子视图,使用removeFromSuperview
添加子视图时,子视图的frame矩阵会确定子视图在父视图中的位置。子视图超过父视图的可视边界时不会被裁剪,要手动把父视图的clipsToBounds属性设为True。
可以在loadView或者viewDidLoad函数中把子视图添加到层次结构中,在loadView中添加子视图,在viewDidLoad中对子视图做额外的配置。
在将子视图从父视图中移除后,若还想继续使用,需要重新持有它,否则会被释放。
在把子视图添加到其他视图的时候,UIKit会通知父视图和所有子视图,对于自定义的视图,可以通过重写willMoveToSuperview:、willMoveToWindow:、willRemoveSubview:、didMoveToSuperview、didMoveToWindow、didAddSubview:方法来打断通知过程。可以使用通知来更新自己的层次结构的状态信息,从而执行额外的任务。
创建视图层次结构之后,可以使用superview和subviews获取对应的视图,每个视图的window属性包含该视图当前显示的窗口。在当前屏幕上的所有视图中,窗口对象是他们的根视图。
b)隐藏视图
把hidden属性设为True或者把alpha属性设为0.0都可以隐藏视图。被隐藏的视图不会接受触摸事件,但是它仍正常参与相关层次结构的autoresizing和布局操作。
⚠️:若一个视图是first reSwiftwiftponder,在把它隐藏后并不会自动改变他的第一响应状态,事件仍然会发送消息给他,因此需要手动强制改变一个要被隐藏的视图的第一响应状态。
要想使视图在隐藏和显示之间切换时有动画,需要使用alpha属性。
c)在视图层次结构中定位视图
- 保存相关视图的引用
- 给每个视图的tag属性赋值一个唯一的整数,然后使用viewWithTag:方法来获取
存储相关视图的引用是最常用的方法,把引用保存在私有的成员变量中,使用的时候要持有它,之后需要释放。
tags是一种减少hard-coded依赖、更加灵活、持久的方法。
d)视图的翻译、缩放、旋转
视图的transform会影响视图外观的最终渲染,常被用来实现滚动、动画、以及其他可视效果。
transform属性包含一个可用于变换的CGAffineTransform结构体,可用来变换视图。
当使用多重变换的时候,把变换添加到CGAffineTransform结构体中的顺序是不一样的。每次操作都是相当于视图中心的。
参考 Transforms in Quartz 2D Programming Guide.
e)改变视图层次结构中的坐标系
大多数情况下尤其是处理事件时都需要转换坐标系。
UIView提供下面几个转换函数,如果把函数中的view赋值为nil,那么就会从包含视图的窗口中转换。
convertPoint:fromView:
convertRect:fromView:
convertPoint:toView:
convertRect:toView:
UIWindow也有下面几个转换函数:
convertPoint:fromWindow:
convertRect:fromWindow:
convertPoint:toWindow:
convertRect:toWindow:
在转换旋转视图的坐标系的时候,转换后的矩形要大,因为转换后的矩形要覆盖转换前的矩形:
1.4 调整视图的大小和位置
1.5 修改视图
1.6 与核心动画层交互
1.7 自定义视图
2.UITableView
-
每个row的高度
var sectionHeaderHeight: CGFloat
每个section的头部的高度
2.1 UITableViewCell
2.2 UITableViewDataSource
func numberOfSections(in: UITableView) -> Int
改变section的个数
func tableView(UITableView, numberOfRowsInSection: Int) -> Int
改变每个section的row的个数
func tableView(UITableView, cellForRowAt: IndexPath) -> UITableViewCell
创建一个要添加到tabview中的cell,并将其返回
2.3 UITableViewDelegate
func tableView(UITableView, heightForRowAt: IndexPath) -> CGFloat
改变指定row的高
func tableView(UITableView, heightForHeaderInSection: Int) -> CGFloat
改变指定section的头部的高
func tableView(UITableView, viewForHeaderInSection: Int) -> UIView?
设置sanction header视图