- iPhone UIKit详解
- 王志刚 王中元 朱蕾编著
- 912字
- 2020-08-28 08:00:21
2.5 UIView的状态监视
UIView中,事先定义了监视UIView状态变化的方法。当创建UIView的子类时,重写这些状态监视方法,可以实现在状态变化的时刻进行各种处理。表2-9中罗列出了UIView的状态监视方法以及各自调用的时机。
表2-9 UIView状态监视方法列表
重写这些方法实现具体处理的实例代码如下。
// 定义UILabel(UIView)的子类 @interface NewLabel :UILabel @end // 实现NewLabel 、重写UIView的状态监视方法 @implementation NewLabel -(void)didAddSubview:(UIView*)subview { NSLog(@"didAddSubview"); } -(void)didMoveToSuperview { NSLog(@"didMoveToSuperview"); } -(void)didMoveToWindow { NSLog(@"didMoveToWindow"); } -(void)willMoveToSuperview:(UIView*)newSuperview { NSLog(@"willMoveToSuperview"); } -(void)willMoveToWindow:(UIWindow*)newWindow { NSLog(@"willMoveToWindow"); } -(void)willRemoveSubview:(UIView*)subview { NSLog(@"willRemoveSubview"); } @end
例如,将此NewLabel作为子元素追加到具体的UIView后,willMoveToSuperview:方法以及didMoveToSuperview 方法将被依次调用,我们可以通过日志具体查看调用过程,日志内容如下。
…… willMoveToSuperview willMoveToWindow didMoveToWindow didMoveToSuperview ……
知识专栏(Column):frame与bounds的区别
我们改变UIView的位置及尺寸时会使用到frame属性。但是,容易引起混淆的是,还有另外一个决定UIView尺寸的bounds属性。实际上,当我们向bounds属性中设置新的CGRect时,UIView的尺寸也会改变(位置没变),与设置frame属性的效果相同。bounds属性到底是什么,该如何使用呢?这里首先将frame与bounds属性各自的作用归纳如下。
- frame属性是以父元素(superview)的本地坐标系为基准的位置及尺寸。
- bounds属性是以自身的本地坐标系为基准的位置及尺寸。
图2-18是上述归纳的示意图,父元素追加到UIWindow中,子元素再追加到父元素中。
图2-18 frame与bounds的关系
此时,父元素的frame.origin属于UIWindow的本地坐标系,值为(100,15)。如此对应,子元素的frame.origin属于父元素的坐标系,值为(0,80)。另外,bounds.origin都是以自身坐标系为基准的,因此值都为(0,0)。
frame属性用于设置UIView位置及尺寸,而bounds属性用于在自己的区域内绘制其他子元素,或者用于判断用户触摸了自身坐标系的什么位置等。
我们可以看一个具体的例子(见图2-19)。例如在坐标(50,15)处已有UIViewA。现在在UIViewA中追加与其相同大小的标签子元素label。
图2-19 追加与UIViewA相同大小的标签
此处的问题是,标签的frame属性中正确的设置值为哪一个。
- label.frame = UIViewA.frame。
- label.frame = UIViewA.bounds。
初看起来正确的答案好像是1,但其实正确的答案为2。frame属性属于父元素的本地坐标系范畴。label.frame中设置的值,从UIViewA的本地坐标系来考虑,应该是(0,0,100,80)。但是 UIViewA.frame的值为(50,15,100,80)。因此向label.frame中设置的正确值是,同样以UIViewA本地坐标系为基准的 UIViewA.bounds,即(0,0,100,80)。