View编程指南(一)


一、View和Window简介

在iOS中,我们用window和view来呈现应用的内容。事实上window本身不能呈现任何可视的内容,但是它可以为view提供基本的容器功能。view相当于定义了window中的一块用于显示内容的区域。例如:用来显示图片、文字、图形或者以上几者的组合的view。你也可以用view来组织和管理其他view。

每个应用都至少有一个window和一个view组成。UIKit和其他系统框架提供了一些预定义的view:从最简单的button、text label到复杂的table view、picker view、scroll view。当预定义的view不能满足你的需求的时候,你还能创建自定义view来管理view的绘制和事件处理。

view是UIView类(或其子类)的实例,它管理应用的window中的一块矩形区域。view负责绘制内容、处理事件、管理subview的布局。绘制内容涉及到使用Core Graphics、OpenGL ES或者UIKit来绘制形状、图片和文字。view同时还负责处理对其矩形区域内发生的触摸或者手势事件。在view的层级结构(hierarchy)中,parent view负责他们的child view的布局并且可以动态的随时调整布局,这在界面旋转或者实现界面动画的情况下尤其有用。

window是UIWindow类的实例并且用于处理应用总的界面呈现。一般来说应用的window基本不会变化:当一个window被创建后,它就待在那儿,只有window里的view会经常发生变化。基本上一个应用就一个window,如果设备接入了外部显示,那么应用会创建第二个window用于在外部显示上呈现内容。

动画用来为用户提供内容变化的视觉反馈。系统定义了在模态化view和不同view之间切换的标准动画。当然view的很多属性也可以使用动画效果,例如:view的透明度、位置、背景色等。如果你直接使用view底层的Core Animation Layer,你还能做出更多炫酷的动画效果。

Interface Builder是一个可视化编辑window和view的工具。使用IB,你的view都存放在一个nib(xib)文件中。你可以把nib文件想像成是存储view和其他对象的序列化资源文件。当你在运行时load一个nib文件的时候,里面的对象会重新组成到内存中并且可以被代码操作。

二、View和Window的结构

1. View结构基础


view和Core Animation Layer配合来处理view的绘制和动画效果。每个view的背后都有一个layer对象(通常是CALayer类的实例)负责这个view的绘制和动画效果。大多数情况下你只需要和UIView的接口打交道,只有在某些特定的情况下你才需要操作layer对象。

为了帮助理解view和layer之间的关系,可以参考图1-1。在图1-1中我们可以看到UIBarButtonItem是没有layer的,因为它是由UIToolbar绘制出来的,并非一个独立的view。

图1-1

2. View的层级结构和Subview管理


当一个view包含另一个view的时候,两个view之间就有了parent-child关系。child view就叫subview,parent view就叫superview。

视觉上,subview的内容遮盖superview全部或部分的内容空间。如果subview是不透明的,那他就彻底遮盖了superview对应的部分。如果subview是部分透明的,那这两个view的内容就会混合在一起显示(想象成高斯模糊的那种效果)。每个superview将它的subview存储在一个排序过的数组里。越晚添加的或者顺序越大的显示在越上面。

superview - subview的这种关系也会影响到一些view的行为。例如:改变superview的大小也会使subview的大小和位置发生改变。还包括改变superview的透明度、改变superview的坐标系统。

view的层级关系还影响到事件的传递。当某个view中发生了触摸事件,如果当前的这个view无法处理,事件会顺着view的层级向上传递。特定的view还会把事件传递给responder对象,例如一个view controller。如果事件最终传递到最顶级的application对象,通常这个事件就被丢弃了。

3. View的绘制周期


UIView使用按需绘制的模式来呈现内容。当一个view首次呈现在屏幕上时,系统会要求它绘制一下它的内容。然后系统会捕捉一张快照,并且一直使用它。如果你不改变view的内容,那么view的绘制代码就不会被再次执行。当你改变了view的显示内容,你应该使用view的setNeedsDisplay或setNeedsDisplayInRect方法来要求重绘。如果你是自定义UIView的子类,那么通常你应该重载drawRect方法来绘制你的view。你也有其他方法来绘制view,例如直接在layer上绘制,但通常你应该重载drawRect来实现自定义view的绘制。

4. View的Content Mode


每个view有一个content mode,当view的几何形状发生变化时,它用来控制view的内容是否需要重绘或者将如何改变。

当你进行如下操作时,content mode将会起作用:

  • 改变view的frame或者bounds的宽高
  • view的transform属性含有scale factor

默认的content mode是UIViewContentModeScaleToFill。它会使view的内容缩放以适应新的frame尺寸。图1-2显示了各种content mode下的内容缩放情况。

图1-2

content mode有助于避免不必要的内容重绘,当然你也可以设置content mode为UIViewContentModeRedraw来强制view在每次缩放或尺寸改变时重绘(调用drawRect方法),但是通常你应当避免这么做。

5. 可拉伸的View


你可以指定view的某块区域为可拉伸,这样当view的尺寸改变的时候,只有可拉伸的区域会受到影响。一般会在按钮上使用这种技术。图1-3显示了可拉伸时,view是如何变化的。

图1-3

使用view的content stretch属性来指定可拉伸的区域。这个属性接受一个rectangle值来表示可拉伸区域,并且这个值会归一化到0.0 - 1.0。这样当拉伸发生时,系统可以用view的当前bounds以及scale factor乘以这个归一化的值来决定如何缩放。另外view的content mode也会影响拉伸。只有UIViewContentModeScaleToFill、UIVieweContentModeScaleAspectFit和UIViewContentModeScaleAspectFill这几个content mode才会出发拉伸。

推荐在设置view的背景时使用一个可拉伸的UIImage对象来实现拉伸

6. 内置动画支持


UIView类的一些属性是支持半自动动画的。你只需要:

  1. 告诉UIKit你要使用动画了!
  2. 改变这些属性的值

这些属性有:

  • frame —— 位置和尺寸的动画
  • bounds —— 尺寸动画
  • center —— 位置动画
  • transform —— 旋转和缩放动画
  • alpha —— 改变透明度
  • backgroundColor —— 改变背景色
  • cententStretch —— 改变view如何拉伸

一般来说,viewcontroller之间过度时会使用动画。当然你也可以直接在两个view之间使用动画。另外,除了使用UIKit类来实现动画,你还能使用Core Animation Layer来实现动画,它能提供更多的时间和属性上的控制。


下篇 View编程指南(二)

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

推荐阅读更多精彩内容