前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >UI篇-VC的生命周期以及UIView的layoutSubviews和drawRect方法

UI篇-VC的生命周期以及UIView的layoutSubviews和drawRect方法

作者头像
進无尽
发布2018-09-12 18:37:12
1.8K0
发布2018-09-12 18:37:12
举报
文章被收录于专栏:進无尽的文章
前言

看似常用的UIView,其实有很多不经常用到的方法和应该注意的机制,我是一个喜欢打破砂锅问到底的人,可是很多问题在网上搜索不到答案,大部分的博客都是转载相同的东西,所以我自己就新建 Dome,实际测试了一些数据,得到了一些有用的东西,分享给大家,其中也用到了其它大神的理论和指点,在此感谢。


viewController的生命周期
  • 单个viewController的生命周期 initWithCoder:(NSCoder *)aDecoder:(如果使用storyboard或者xib) loadView:#加载view 会多次调用并且会使viewWillLayoutSubviews、viewDidLayoutSubviews不再执行 viewDidLoad:view加载完毕 viewWillAppear:控制器的view将要显示 viewWillLayoutSubviews:控制器的view将要布局子控件 viewDidLayoutSubviews:控制器的view布局子控件完成 viewDidAppear:控制器的view完全显示 viewWillDisappear:控制器的view即将消失的时候 viewDidDisappear:控制器的view完全消失的时候
  • 多个viewControllers跳转 当我们点击push的时候首先会加载下一个界面然后才会调用界面的消失方法 initWithCoder:(NSCoder *)aDecoder:ViewController2 (如果用xib创建的情况下) loadView:ViewController2 viewDidLoad:ViewController2 viewWillDisappear:ViewController1 将要消失 viewWillAppear:ViewController2 将要出现 viewWillLayoutSubviews ViewController2 viewDidLayoutSubviews ViewController2 viewWillLayoutSubviews:ViewController1 viewDidLayoutSubviews:ViewController1 viewDidDisappear:ViewController1 完全消失 viewDidAppear:ViewController2 完全出现
  • 小结: 整个控制器声明周期: viewDidLoad -> viewWillAppear -> viewWillLayoutSubviews -> viewDidLayoutSubviews -> viewDidAppear -> viewWillDisappear -> viewDidDisappear
  • 说明

viewWillLayoutSubviews 在 viewWillAppear 之后 viewDidAppear 之前执行,这个方法会被调用多次,如果在此创建视图,可能会创建多个,而且这个方法中执行耗时操作依然会造成跳转卡顿的问题。 一个VC 在执行viewWillDisappear 或者viewDidDisappear 方法时都是出栈之后才执行的,也就是说 已经不在 self.navigationController 的viewControllers中了,而一个 VC 执行viewWillAppear 时必定是 self.navigationController 的 topViewController即栈顶的视图。 一个很常见的问题,我们需要在VC被销毁的时候处理一些事情,可是 viewWillDisappear 不管是入栈新的视图还是出栈当前视图都会被调用,无法判断,结合我之前说的原理,我们可以利用下面这个方法判断当前VC是否是被出栈了。 - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:YES]; if ([[self.navigationController viewControllers] containsObject:self ]) { NSLog(@"TwoViewController 暂时消失"); }else { NSLog(@"TwoViewController 出栈了"); } }

**首先需要特别说明的一点是: **

在使用 VC绘制UI的时候,它不同于 UIView,UIView中 init方法调用后,UIView就已经绘制好(初始化好了)。

但是在VC中,当前UIView的是在 viewDidLoad 执行后才初始化好的,所以我们会见到这样一个Bug,在VC初始化语句后面调用 一个 VC的绘制UI的方法,你会发现根本没有效果,这就是因为,VC中跟试图的初始化是需要时间的,你在VC根试图初始化之前调用绘制UI的方法当然是不会有效果出现的。

</br>

UIView的setNeedsDisplay和setNeedsLayout方法。

首先两个方法都是异步执行的。setNeedsDisplay会调用 drawRect方法,这样可以拿到UIGraphicsGetCurrentContext,就可以画画。 setNeedsLayout会默认调用layoutSubViews,就可以处理子视图中的一些数据。

**综上两个方法都是异步执行的,layoutSubviews方便数据计算,drawRect方便视图重绘。UIView中方法的执行顺序大概是这样的:

init 方法 >>属性的set/get 方法>> layoutSubviews(当然是要达到触发条件)>>drawRect, 使用得当可以在View的调用中起到很好的效果。

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

代码语言:javascript
复制
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在以下情况下会被调用:

代码语言:javascript
复制
 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方法使用注意点:

代码语言:javascript
复制
1、 **若使用UIView绘图,只能在drawRect:方法中获取相应的contextRef并绘图。如果在其他方法中获取将获取到一个invalidate 的ref并且不能用于画图**。**drawRect:方法不能手动显示调用,必须通过调用setNeedsDisplay 或 者 setNeedsDisplayInRect,让系统自动调该方法。强行调用也不会起作用的。**
2、**若使用calayer绘图,只能在drawInContext: 中(类似鱼drawRect)绘制**,或者在delegate中的相应方法绘制。同样也是调用setNeedDisplay等间接调用以上方法
3、**若要实时画图,不能使用gestureRecognizer,只能使用touchbegan等方法来掉用setNeedsDisplay实时刷新屏幕。**

setNeedsDisplay和setNeedsLayout 详解

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016.08.28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • viewController的生命周期
  • UIView的setNeedsDisplay和setNeedsLayout方法。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档