UIView(包括子类)的几个初始化时执行动作的时机

转载自:http://www.tqcto.com/article/mobile/56963.html

根据你需要执行的动作, 这里有几个方法:

  • -(id)initWithFrame:(CGRect)frame - UIView的指定初始化方法; 总是发送给UIView去初始化, 除非是从一个nib文件中加载的;
  • -(id)initWithCoder:(NSCoder *)coder - 从nib文件中加载的时候发送此消息给UIView;
  • -(void)awakeFromNib - 在所有的nib中的对象初始化和连接后将发送此消息; 只适用于从nib加载对象; 如要重写,其中还必须调用父类的awakeFromNib;
  • -(void)willMoveToSuperview:(UIView *)newSuperview - 在一个子视图将要被添加到另一个视图的时候发送此消息;
  • -(void)willMoveToWindow:(UIWindow *)newWindow - 在一个视图(或者它的超视图)将要被添加到window的时候发送;
  • -(void)didMoveToSuperview - 把一个视图插入到视图层级之后发送此消息;
  • -(void)didMoveToWindow - 当视图获得它的window属性集的时候发送此消息.

基本上, 你能选择: 在你的视图初始化期间执行的动作 (1 & 2), 在从nib文件中加载的时候 (3), 在插入到视图层级之前 (4 & 5) 和 之后 (6 & 7)

layoutSubviews方便数据计算,drawRect方便视图重绘。

layoutSubviews在以下情况下会被调用:

1、init初始化不会触发layoutSubviews。

2、addSubview会触发layoutSubviews。

3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。

4、滚动一个UIScrollView会触发layoutSubviews。

5、旋转Screen会触发父UIView上的layoutSubviews事件。

6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件。

7、直接调用setLayoutSubviews。

drawRect在以下情况下会被调用:

1、如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。drawRect 掉用是在Controller->loadView, Controller->viewDidLoad 两方法之后掉用的.所以不用担心在 控制器中,这些View的drawRect就开始画了.这样可以在控制器中设置一些值给View(如果这些View draw的时候需要用到某些变量 值).

2、该方法在调用sizeToFit后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。

3、通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。

4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。

以上1,2推荐;而3,4不提倡

drawRect方法使用注意点:

1、 若使用UIView绘图,只能在drawRect:方法中获取相应的contextRef并绘图。如果在其他方法中获取将获取到一个invalidate 的ref并且不能用于画图。drawRect:方法不能手动显示调用,必须通过调用setNeedsDisplay 或 者 setNeedsDisplayInRect,让系统自动调该方法。

2、若使用calayer绘图,只能在drawInContext: 中(类似鱼drawRect)绘制,或者在delegate中的相应方法绘制。同样也是调用setNeedDisplay等间接调用以上方法

3、若要实时画图,不能使用gestureRecognizer,只能使用touchbegan等方法来掉用setNeedsDisplay实时刷新屏幕

时间: 2024-08-06 03:33:08

UIView(包括子类)的几个初始化时执行动作的时机的相关文章

页面初始化时执行js方法

1.<script>      window.onload=function(){      alert("");     }    </script> 2.function ckCbo(){alert(""); }<body onload='ckCbo()'> jQuery页面加载初始化的3种方法 1.$(document).ready(function(){     alert("方法1.");     

UI --UIView 及其子类

一 > UIView 1> iOS 概述: iOS 是 Apple 公司的移动操作系统,主要用于iPhone, iPad, iPad Mini , iPod Touch 等移动产品. 借助iOS 我们可以开发视频类 , 美图类 , 音乐类 , 团购类 ,电商类 ,出行类, 生活类 ,生活服务类 , 游戏类 ...应用程序 除此之外,ios还可以与外部设备通信,开发出更多改变生活的产品,比如:智能家居( ios App 控制电视,空调..  ) , 健身产品 ( 将人体的健康状况通过App 直观

UIView及其子类 &#160;UILabel

UI概述 UI(User Interface):?用户界?面,?用户能看到的各种各样的?页?面元素. iOS App = 各种各样的UI控件 + 业务逻辑和算法. 什么是window? window是窗?口,每个app都需要借助window将内容展现给?用户看. 在iOS中,使?用UIWindow类来表?示窗?口,通常?一个应?用程序只创建 ?一个UIWindow对象. window的主要作用是呈现内容给用户,我们不会对window做太多操作. 如何创建window? 通常window的大小(f

UIView及其子类

一.UI概述 UI(User Interface):用户界?,用户能看到的各种各样的?面元素. iOS App = 各种各样的UI控件 + 业务逻辑和算法 二.UIView 在手机上显示的内容都是UIView或者是UIView的子类.UIView是用来与用户进行交流的层级上很重要的一个类. UIView继承于UIResponder,所以UIView继承了UIResponder的属性和方法,其中最常用的方法就是触摸事件,这是用户与APP进行信息交流的主要途径之一. UIView的初始化方法是ini

html---textarea初始化时就有个table空格以及tab键操作无效

1 初始化时就有一个tab空格 这是因为<textarea></textarea>之间的内容不为空的原因,包括空格和换行,否则浏览器会认为空格或者换行都是文本域的内容,因此书写时需将<textarea></textarea>紧靠在一起: 2 tab键对textarea操作无效 在textarea中使用tab键时是无效的,会切换到另一个控件上去,但是当我们有个需要时,要能够在文本域中使用tab键,可以使用javascript或者jquery方式实现: 方式1:

ios uiimage初始化时的两种方法

第一种方式:UIImage *image = [UIImage imageNamed:@"image"]; 使用这种方式,第一次读取的时候,先把这个图片存到缓存里,下次再使用时直接从缓存中读取:优点:只有第一次使用的时候稍慢,接下来在使用就会稍快:缺点:如果在当前工程中只使用一次会浪费内存. 第二种方式:initWithContentsOfFiles初始化时,每次都会根据路径去读取,不会占用内存,如果图片在当前工程中只使用一次,应该选择这个方法.

Java类静态属性、静态块、非静态属性、非静态块、构造函数在初始化时的执行顺序

前言 今天在看Android ContentProvider实现的时候,突然想到了Java类在new的过程中,静态域.静态块.非静态域.非静态块.构造函数的执行顺序问题.其实这是一个很经典的问题,非常考察对Java基础知识的掌握程度.很多面试过程中相信也有这样的问题,趁着周末有时间复习一下. 结论 这里先把整理好的结论抛给大家,然后我在写个程序来验证我们的结论.在Java类被new的过程中,执行顺序如下: 实现自身的静态属性和静态代码块.(根据代码出现的顺序决定谁先执行) 实现自身的非静态属性和

spring在web容器启动时执行初始化方法

需求:在tomcat启动时开启一个定时任务. 想法:容器启动时执行方法,最容易想到的就是servlet中可以配置load-on-startup,设置一个正整数也就可以随容器一起启动. 问题:上面的方法很好,但是由于定时任务需要去操作数据库,而项目采用了spring的依赖注入来管理对象,而servlet并不受Spring的管理.若此时在servlet中注入Spring管理的对象,则会报错:javax.naming.NameNotFoundException: Name com.test.InitS

遍历UIView的子类

for (id view in self.view.subviews) { if ([view isKindOfClass:[UITextField class]]) { UITextField* textField = (UITextField*)view; [textField resignFirstResponder]; } } 遍历UIView的子类