原文转自http://stackoverflow.com/questions/2807137/what-is-the-relationship-between-uiviews-setneedslayout-layoutifneeded-and-lay
重新布局:VC的view里有一个自定义的customView,这个customView的bounds是{0,0,300,300},这个时候,你需要在点击这个customView的时候,让他的bounds扩大到{0,0,500, 500},那么这个时候,customView里面的子控件是依托于这个customView的左上角进行布局的,那么这个时候按照正常的理论,它内部的子控件是需要重新再来调整一次布局的,这个就是重新布局,重新布局的时机很多:比如改变当前view的bounds,旋转屏幕,拖动scrollView
【view layoutSubviews】是一种让人崩溃的写法,因为这个方法的触发时机根本就不是手动去调用,而是通过调用setNeedsLayout或者layoutIfNeeded来触发
setNeedsLayout这个方法是给需要改变的view设置flag(flag就是单独的指一个标志,并不是还是必须就是flag这个变量),标示这个view即将要被重新布局,会唤起layoutSubviews这个方法
如果没有调用layoutIfNeeded,唤起layoutSubViews的时机会是下一次runloop进行重绘内容之前,如果手动调用了这个view的layoutIfNeeded,就会立马调用这个view的layoutSubviews方法进行布局改变
最常见的手动去调用layoutIfNeeded就是,用约束布局的时候,做动画,setNeedsLayout不是重绘,是重新布局,重绘是setNeedsDisplay,既然重新布局,必然也会重绘。那么如果没有调用layoutIfNeeded 但是给setNeedsLayout的flag设置标志要求重绘,那么并不会调用layoutSubviews,时机是下一次的runloop