更新:2018.05.24
整理了一下demo:SwiftDemo
UIView是UIKit框架里面最基础的试图类,UIView类定义了一个矩形的区域,并管理该区域内的所有屏幕显示。
iOS应用中,每个视图都要负责渲染试图矩形区域的内容,并响应该区域中发生的事件,这一双重行为意味着视图是应用程序与用户交互的重要机制。
图是在网上找的:
-
NSObject:
NSObjec
t是一个根类,几乎所有的类都是冲它派生出来的,根类拥有所有类都有的方法,alloc、init
等。 - UIResponder:可以让继承它的类响应移动设备的触碰事件,由于可能存在多个对象响应同一事件,所以iOS将事件沿响应链向上传递。
-
UIView:
UIview
是所有控件的父类,控件用于响应用户的交互,而UIView负责显示和布局。 -
UIWindow:
UIWindow
提供了一个用于管理和显示视图的窗口。窗口提供一个描画内容的表面,是所有其他视图的根容器。每个应用程序通常都只有一个窗口。 -
UIControl:
UIControl
几乎是所有交互控件的父类,如按钮、滑块、文本框等。所以UIControl
负责根据碰触事件出发响应的动作。
UIWindow
- UIView视图和UIWindow窗口是iOS应用程序构造洪湖界面的可视视图。超扣为内容显示提供平台,而视图负责绝大部分的内容描述和响应用户交互。
- 程序启动后,创建的第一个视图就是UIWindow,接着创建视图控制器的view,并把view放到UIWindow上,于是控制器的view就显示在屏幕上了。
- 当view显示到屏幕上之后,除非有特殊操作,不然就很少再使用到window了。
- 尽量不要创建多个窗口,尽管iOS是支持多个窗口同时存在的。
1.UIView外观
UIView外观常用的主要有背景颜色、切边、透明度、显示与吟唱。
let testView = UIView()
// 坐标
testView.frame = CGRect(x: 100, y: 100, width: 50, height: 50)
// 背景颜色
testView.backgroundColor = UIColor.black
// 是否切除子视图超出部分
testView.clipsToBounds = true
// 透明度
testView.alpha = 0.5
// 是否隐藏视图
testView.isHidden = false
// 添加到当前视图控制器
view.addSubview(testView)
a. 上述代码中,我们建立了一个位置在(100,100),宽高都是50的UIView
视图。frame
的作用是确定视图的位置及大小。
-
UIView的frame(origin,size)属性:定义了一个矩形,描述
UIView
的大小和在父系坐标系中的位置。 -
UIView的bounds(origin,size)属性:同样定义一个矩形,描述一个
UIView
的大小和自身坐标系中的位置,通常bounds.origin
的属性是 (0,0),而bounds.size
和frames.size
是一致的。 -
UIView的center属性:用于确定一个视图的中心位置,其参照系也是其俯视图的坐标系。在对视图进行放大、缩小或旋转时,
center
属性不会变。
b. 设置背景颜色是黑色,UIColor
是继承自NSObjec
t的一个储存颜色的类,包含了颜色和透明度的值
可以看出,它提供了一些最常使用颜色的类方法。同时也有
RGB
设置颜色和透明度的方法c. clipToBounds
属性用于限制子视图的显示范围不能超过父视图的显示区域,如果设置为true
,超出部分将被切除。
let testView2 = UIView(frame: CGRect(x: 20, y: 20, width: 50, height: 50))
testView2.backgroundColor = UIColor.green
testView.addSubview(testView2)
代码中我们在
testView
中又建立了一个同样大小的testView2
,坐标在(20,20),可以看出,因为testView
中clipToBounds
设置了true
,所以testView2
超出部分被切掉了。
d. alpha
负责视图的透明度,上面的途中可以看出,黑色中透着红色,是因为我们设置了0.5的透明度,也就是半透明状态。透明度的取值范围是0~1.0。
在视图上添加透明度之后,会使子视图也有相同的透明度。
如果当前view
的alpha
是0,那么view
及其子视图会一同消失,不论子视图的alpha
是多少。
同时,view
会从响应链中移除,而响应链中的下一个会成为第一响应者。
e.isHidden
负责视图的隐藏与显示,默认是false
。
如果当前view
的isHidden
是true
,view
及其子视图都会被隐藏,不论子视图的isHidden
是什么。
同时,view
会从响应链中移除,而响应链的下一个会成为第一响应者。
2. UIView嵌套和层级关系
视图可以通过嵌套的方式,组成复杂的层级结构。
- 视图可能包含按钮、标签、图像等控件,这些控件被称为子视图,而包含他们的视图被称为父视图。
- 一个视图可以包含任意数量的子视图,通过为子视图添加子视图的方式,可以实现任意深度的嵌套。
- 视图在视图层次中的组织方式䦺了屏幕上显示的内容,因为指示图总是被显示在父视图的上方,这个组织方式还决定了视图如何响应时间和变化。
- 每个父视图还负责管理其直接的子视图,根据需要调整他们的位置和尺寸,以及响应他们没有处理的事件。
方法名 | 描述 |
---|---|
removeFromSuperview() |
将子视图从父视图中删除。 |
addSubview(view:) |
添加视图,加在父视图层级结构的最上层。 |
insertSubview(view:,at:) |
在指定位置插入视图 |
insertSubview(view:,belowSubview:) |
将视图添加到指定视图的下方。 |
insertSubview(view:,aboveSubview:) |
将视图添加到指定是图的上方。 |
exchangeSubview(at:,withSubviewAt:) |
交换2个指定位置的子视图在父视图中的位置。 |
bringSubview(toFront:) |
将指定子视图移动到最前面。 |
sendSubview(toBack:) |
将指定子视图移动到最后面。 |
这边就不上代码了。
3.UIView交互属性
- 设置
UIView
的userInteractionEnabled
属性,可以设置用户的交互特性,这个属性决定UIView是否接受并响应用户的交互。 - 当属性值为
false
时,UIView
会忽略那些发生在其自身的如触摸、键盘等用户事件,并将这些事件从消息列表中移除。 - 当属性值为
true
时,这些用户事件会正常派发至UIView
本身,UIView会按照之前注册的事件处理方法来响应相应的事件。
let touchView = UIView.init(frame: CGRect(x: 100, y: 240, width: 150, height: 150))
touchView.isUserInteractionEnabled = true
touchView.backgroundColor = UIColor.black
view.addSubview(touchView)
let tap = UITapGestureRecognizer(target: self, action: #selector(touchViewClick))
touchView.addGestureRecognizer(tap)
func touchViewClick() {
print("You touched me!!!")
}
a. 上面代码中,我们创建了一个touchView
视图,设置背景颜色为黑色,并给它添加了一个点击手势。
b. 当点击touchView
的时候,会输出You touched me!!!
c. 如果将isUserInteractionEnabled
属性设置为false
,那么这个方法将不被执行。
4.UIView变形操作
-
CGAffine Transform
仿射转换结构体代表了一种用于放射变换的矩阵。 - 结构体的参数指定了从一个坐标系的点转化成另外一个坐标系的点的规则。
- 仿射变换是一种特殊类型的映射,保留在一个路径中的平行线,但不一定保留长度或角度。
- 我们通常不会创建一个仿射变换,只需要根据现有的参数,修改现有的仿射变换。
几种常用的仿射变换:
名称 | 说明 |
---|---|
translatedBy(x:,y:) |
对已存在的矩阵进行平移 |
scaledBy(x:,y:) |
对已存在的矩阵进行缩放 |
rotated(by:) |
对已存在的矩阵进行旋转 |
inverted() |
对已存在的矩阵进行反转 |
concatenating(t2:) |
对仿射效果进行叠加操作 |
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
let view_t = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
view_t.backgroundColor = UIColor.black
view_t.center = view.center
view.addSubview(view_t)
let transform = view_t.transform
// 向下平移200像素
view_t.transform = transform.translatedBy(x: 0, y: 200)
}
a. 上面代码中,我们创建了一个view_t
,宽度200高度50,位置在屏幕中间。颜色为黑色。
b. 在没有添加
transform
时,跑一下项目会发现view_t
在屏幕中间显示,后面我们加了transform
的平移操作,跑一下项目会发现view_t
向下平移了200。
c.现在我们把平移换成缩放仿射变换,让它缩小一半:
view_t.transform = transform.scaledBy(x: 0.5, y: 0.5)
跑一下项目会发现
view_t
缩小了一半,同理,如果是放大的话,就让x和y的值按照要求增大,比如放大到1.5倍:
view_t.transform = transform.scaledBy(x: 1.5, y: 1.5)
d. 接下来我们在看一下旋转仿射变换,依然用这个例子,更换transform
,为rotate
,比如旋转45度:
view_t.transform = transform.rotated(by: CGFloat(Double.pi/4))
Double.pi
是圆周率π
,OC中一般是M_PI
,但在这报黄,系统推荐用这个。
e. 继续我们看一下斜切仿射变换,我们上面用的平移、缩放、旋转都是系统封装好的,系统并没有提供类似于CGAffineRransformRoate
方法的斜切操作方法。所以我们要使用transform
的init
方法自己创建。
public init(a: CGFloat, b: CGFloat, c: CGFloat, d: CGFloat, tx: CGFloat, ty: CGFloat)
参数名 | 说明 |
---|---|
a |
水平方向上的缩放因子 |
b |
水平方向上的斜切因子 |
c |
垂直方向上的斜切因子 |
d |
垂直方向上的缩放因子 |
tx |
水平方向上的位移因子 |
ty |
垂直方向上的位移因子 |
我们可以在代码中这样设置
transform.a = 1.0
transform.b = 0.5
transform.c = 0.5
transform.d = 1.0
transform.tx = 0.0
transform.ty = 0.0
view_t.transform = transform
- 其中a和d的值都是1,即保持缩放大小不变
- b和c都是0.5 即在水平和垂直方向进行斜切操作
- tx和ty的值都是0,即水平和垂直方向不进行位移
OK,UIView的方面大概先到这里。刚开始截图的时候图片是白色的,不是很清晰,换了背景色重新截图的。