iOS开发之窗口和视图
视图就是应用程序的界面。视图可以使用nib文件实现,也可以使用代码创建。一个视图也是一个响应器(UIResponder的子类)这意味着一个视图可以与用户交互。因此,视图不只是用户可看到的界面,也是可以和用户交互的界面。
- CGPoint {x,y} 坐标信息 视图所在的坐标信息
- CGSize {width,height} 宽度和高度 视图所在的大小信息
- CGRect {origin,size} CGPoint和CGSize的综合 视图所在的坐标(视图最左上角的点)和大小信息。
- CGPointMake(x,y) 声明位置信息
- CGSizeMake(width,height) 声明大小信息
- CGRectMake(x,y,width,height) 声明位置和大写信息
视图的位置和大小可以用两种方式来表示,一种方式是Frame(框架)、即按照其父视图为起点,得出它自己的位置信息。另一种方式是Bound(边界),即按照它自己为起点,得出其位置。
frame和bounds是UIView中的两个属性(property)。
frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)
bounds指的是:该view在本身坐标系统中 的位置和大小。(参照点是本身坐标系统)
-(CGRect)frame{
return CGRectMake(self.frame.origin.x,self.frame.origin.y,self.frame.size.width,self.frame.size.height);
}
-(CGRect)bounds{
return CGRectMake(0,0,self.frame.size.width,self.frame.size.height);
}
下图中View B是View A的子视图,那么,View B的frame属性为origin(200,100),size(200,250),而View B的bounds属性为origin(0,0),size(200,250)。
center属性则用CGPoint表示矩形中心点在其父视图中的位置,如上图中View B的center属性为(300,200)。
frame、bounds和center三个属性是相互关联、相互影响的,其中一个属性发生变化,其他属性也会跟着变化。
- A
UIScreen
object that identifies a physical screen connected to the device. - A
UIWindow
object that provides drawing support for the screen. - A set of
UIView
objects to perform the drawing. These objects are attached to the window and draw their contents when the window asks them to.
类的继承关系
UIScreen对象代表iOS设备的物理屏幕([UIScreen mainScreen])。此屏幕对象建立视图布局边界与像素空间之间的映射。它返回全屏大小(bounds)或只是应用程序占用的矩形(applicationFrame)。
CGrect screenBounds = [ [UIScreen mainScreen] bounds];//返回的是带有状态栏的Rect
对于iphone4来说screenBounds=0,0,320,480
CGRect viewBounds = [ [UIScreen mainScreen] applicationFrame];//不包含状态栏的Rect
对于iphone4来说,viewBounds=0,20,320,460
视图层次的最高层是应用程序窗口,窗口是UIWindow的一个实例,UIWindow是UIView的子类 。窗口的主要功能一是提供一个区域显示视图(容器),二是将事件分发给视图。窗口本身不具有任何可见的内容,但它对于应用的视图提供一个基本的窗口。应用程序应该只有一个主窗口,它占据整个屏幕形成背景,并是所有可见视图的超视图,其他视图就是它的子视图。
窗口是项目的主nib文件中的一个顶层nib对象。在应用程序运行时,系统自动装载该nib文件,窗口被实例化。主nib文件中的另一个顶层的nib对象是应用程序委托(delegate),它有一个window输出口(outlet)指向这个窗口。当程序运行时,系统生成该应用程序委托的一个实例。它的window属性指向窗口。
通常我们可以采取两种方法将view添加到UIWindow中:
1、addSubview
直接将view通过addSubview方式添加到window中,程序负责维护view的生命周期以及刷新,但是并不会为去理会view对应的ViewController,因此采用这种方法将view添加到window以后,我们还要保持view对应的ViewController的有效性,不能过早释放。
2、rootViewController
rootViewController是UIWindow的一个遍历方法,通过设置该属性为要添加view对应的ViewController,UIWindow将会自动将其view添加到当前window中,同时负责ViewController和view的生命周期的维护,防止其过早释放
UIWindow在显示的时候会根据UIWindowLevel进行排序的,即Level高的将排在所有Level比他低的层级的前面。下面我们来看UIWindowLevel的定义:
typedef CGFloat UIWindowLevel;
UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal;
UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert;
UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar;
iOS系统中定义了三个window层级,其中每一个层级又可以分好多子层级(从UIWindow的头文件中可以看到成员变量CGFloat _windowSublevel;),不过系统并没有把则个属性开出来。UIWindow的默认级别是UIWindowLevelNormal。UIWindowLevelNormal<UIWindowLevelStatusBar<UIWindowLevelAlert.
视图是UIView类的实例,负责在屏幕上定义一个矩形区域。在iPhone的应用程序中,视图在展示用户界面及响应用户界面交互方面发挥关键作用。每个视图对象都要负责渲染 视图矩形区域中的内容,并响应该区域中发生的触碰事件。这一双重行为意味着视图是应用程序与用户交互的重要机制。在一个基于模型-视图-控制器的应用程序中,视图对象明显属于视图部分。
UIView有一个超视图(superview)属性和一个子视图(subviews)属性。subviews是一个UIViews的NSArray,按照由后往前的顺序放置。这有助于在代码中访问视图层次结构。isDescendantOfView方法可以判断一个视图是否是另一个视图的子视图。
UIView提供了很多建立和管理视图的方法。
1、添加视图
- insertSubview:atIndex: //放在子视图数组的具体索引位置
- insertSubview:aboveSubview: //某个子视图前面
- insertSubview:aboveSubview: //某个子视图前面
2、重新排序和删除子视图
- [parentView exchangeSubviewAtIndex:i withSubviewAtIndex:j]//交换两个视图的位置
- bringSubviewToFront:和sendSubviewToBack://将子视图提前活置后
- [childView removeSuperview]//删除某个视图的子视图
3、视图回调
某个视图的层次一改变,该视图就会收到一次回调。
- a、调用addSubivew:成功后会给该视图发送didAddSubivew:回调,触发UIView的子类在心增视图时执行其他操作。
- b、didMoveToSuperview:会通知相关视图他们的上级视图已经变化。
- c、视图移动前会发出willMoveToSuperview:回调
- d、didMoveToWindow:回调和didMoveToSuperview:相似,从命名上能看出其区别。
- e、willMoveToWindow:在视图移动前发出的回调。
- f、willRemoveToSubview:回调通知父视图子视图即将被删除
UIView掌管直接屏幕绘图。他的drawRect:方法提供一种低级方式来直接绘制内容,允许使用Quartz 2D调用创建和显示任意元素,可将这两个元素结合起来共同构建具体、可操作的界面。
当用户触摸屏幕时,Touchview类收集一系列点,在每个触摸移动之处,touchesMoved:WithEvent:方法调用setNeedsDisplay。这又会触发对drawRect:方法的调用,其中视图将这些点绘制成线段来创建一个可视屏幕路径。