Swift(十)UIView

更新:2018.05.24

整理了一下demo:SwiftDemo


UIView是UIKit框架里面最基础的试图类,UIView类定义了一个矩形的区域,并管理该区域内的所有屏幕显示。
iOS应用中,每个视图都要负责渲染试图矩形区域的内容,并响应该区域中发生的事件,这一双重行为意味着视图是应用程序与用户交互的重要机制。

图是在网上找的:

  • NSObject:NSObject是一个根类,几乎所有的类都是冲它派生出来的,根类拥有所有类都有的方法,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.sizeframes.size是一致的。
  • UIView的center属性:用于确定一个视图的中心位置,其参照系也是其俯视图的坐标系。在对视图进行放大、缩小或旋转时,center属性不会变。

b. 设置背景颜色是黑色,UIColor是继承自NSObject的一个储存颜色的类,包含了颜色和透明度的值


可以看出,它提供了一些最常使用颜色的类方法。同时也有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),可以看出,因为testViewclipToBounds设置了true,所以testView2超出部分被切掉了。

d. alpha 负责视图的透明度,上面的途中可以看出,黑色中透着红色,是因为我们设置了0.5的透明度,也就是半透明状态。透明度的取值范围是0~1.0。
在视图上添加透明度之后,会使子视图也有相同的透明度。
如果当前viewalpha是0,那么view及其子视图会一同消失,不论子视图的alpha是多少。
同时,view会从响应链中移除,而响应链中的下一个会成为第一响应者。

e.isHidden 负责视图的隐藏与显示,默认是false
如果当前viewisHiddentrueview及其子视图都会被隐藏,不论子视图的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交互属性

  • 设置UIViewuserInteractionEnabled属性,可以设置用户的交互特性,这个属性决定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方法的斜切操作方法。所以我们要使用transforminit方法自己创建。

    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的方面大概先到这里。刚开始截图的时候图片是白色的,不是很清晰,换了背景色重新截图的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 曾经有人这么说过,在iphone里你看到的,摸到的,都是UIView,所以UIView在iphone开发里具有非常...
    我是一只攻城狮_ifYou阅读 622评论 0 2
  • 7、不使用IB是,下面这样做有什么问题? 6、请说说Layer和View的关系,以及你是如何使用它们的。 1.首先...
    AlanGe阅读 655评论 0 1
  • 在iOS开发中经常会涉及到触摸事件。本想自己总结一下,但是遇到了这篇文章,感觉总结的已经很到位,特此转载。作者:L...
    WQ_UESTC阅读 5,988评论 4 26
  • 好奇触摸事件是如何从屏幕转移到APP内的?困惑于Cell怎么突然不能点击了?纠结于如何实现这个奇葩响应需求?亦或是...
    Lotheve阅读 56,614评论 51 597
  • 李亚鹏的子女教育观摘录: 我希望我的女儿能成为一个有爱、有才情、不轻易被打败的人。 有爱: 上帝给了你伤痕,我要让...
    好西好阅读 392评论 0 0