美文网首页
layoutSubviews、drawRect与sizeToFi

layoutSubviews、drawRect与sizeToFi

作者: 烟雨任平生YL | 来源:发表于2019-06-24 10:13 被阅读0次

    1.layoutSubviews
    官方说明:
    这个方法,默认没有做任何事情,子类可以根据需要覆盖此方法,以执行其子视图的更精确布局。
    您不应该直接调用此方法。 如果要强制进行布局更新,请在下次绘图更新之前调用setNeedsLayout方法。
    如果要立即更新视图的布局,请调用layoutIfNeeded方法。
    调用时机:
    1.init初始化不会触发layoutSubviews;但是是用initWithFrame 进行初始化时,当rect的值不为CGRectZero时, addSubview也会触发
    2.addSubview会触发layoutSubviews
    3.设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化(因此在layoutSubviews中设置frame不会造成循环);
    4.滚动一个UIScrollView会触发layoutSubviews
    5.旋转Screen会触发父UIView上的layoutSubviews事件
    6.单纯改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件
    7.setNeedsLayout方法(异步)、-layoutIfNeeded方法(马上)会调用layoutSubviews进行布局
    总结:layoutSubviews, 当我们在某个类的内部调整子视图位置时,需要调用。反过来的意思就是说:如果你想要在外部设置subviews的位置,就不要重写。
    -layoutSubviews方法:这个方法,默认没有做任何事情,需要子类进行重写
    -setNeedsLayout方法: 标记为需要重新布局,异步调用layoutIfNeeded刷新布局,不立即刷新,但layoutSubviews一定会被调用
    -layoutIfNeeded方法:如果,有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews)
    如果要立即刷新,要先调用[view setNeedsLayout],把标记设为需要布局,然后马上调用[view layoutIfNeeded],实现布局。
    layoutSubviews方法调用先于drawRect


    2.drawRect:(CGRect)rect执行重绘任务
    可以在UIView(UIViewRendering)的方法- (void)drawRect:(CGRect)rect;中去绘制一些我们所需要的图形,如虚线、圆形、方形以及曲线等等图形 ,重写此方法,执行重绘任务。
    调用时机:
    1、如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用;在子类初始化时调用- (instancetype)initWithFrame:(CGRect)frame方法,且frame不为CGRectZero时会调用
    2、该方法在调用sizeThatFits后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。
    3、通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。
    4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0.
    5、drawRect是在Controller->loadView, Controller->viewDidLoad之后会自动调用,调用时机是在viewWillAppear和viewDidAppear之间
    使用说明:
    只能在继承了UIView的子类中通过重写drawRect方法来绘制图形; 如果需要绘制图形的子类直接继承自UIView,则子类的drawRect方法中不需要调用父类方法[super drawRect:rect];如果子类继承自其他继承UIView的View类,则drawRect方法中需要调用父类方法[super drawRect:rect];
    补充:
    -setNeedsDisplay方法:标记为需要重绘,异步掉用drawRect
    -setNeedsDisplayInRect:(CGRect)invalidRect方法:标记为需要局部重绘
    比较:
    layoutSubviews对subviews重新布局;drawRect是对receiver的重绘,能获得context;
    layoutSubviews方法调用先于drawRect;
    setNeedsLayout在receiver标上一个需要被重新布局的标记,在系统runloop的下一个周期自动调用layoutSubviews;layoutIfNeeded方法如其名,UIKit会判断该receiver是否需要layout.
    layoutIfNeeded遍历的不是superview链,应该是subviews链
    setNeedDisplay在receiver标上一个需要被重新绘图的标记,在下一个draw周期自动重绘,iphone device的刷新频率是60hz,也就是1/60秒后重绘。


    3.sizeToFit: resize当前view,使得它找到最适合自己的大小.通常是通过view内容来确定它自己的大小.不要重写这个方法.
    sizeToFit会计算出最优的 size 而且会改变自己的size
    sizeThatFits: 会计算出最优的 size 但是不会改变 自己的size
    使用这两个方法必须先给label赋值。
    常用场景
    UILabel中,先设置label view的width,然后使用sizeToFit,会根据内部文字多少,自适应返回当前label的size,其中height就是系统自动计算的.(ps:这里也可以用NSString的boundingRect方法计算文字宽高,然后设置给label)
    UIImageView, 如果该imageView中有图片,调用sizeToFit,返回的size就是内部图片的size
    UISwitch, 这个控件的默认size是固定的,调用以后返回默认的size.(ps:如果需要改变大小,使用transform属性)
    navigationItem, 如果设置它使用customView时候,最好先调用sizeToFit
    补充:UILabel中有一个关键属性adjustsFontSizeToFitWidth,可以通过label的width反向自适应设置字体的font.注意这个属性需要配合baselineAdjustment=UIBaselineAdjustmentAlignCenters一起使用.

    相关文章

      网友评论

          本文标题:layoutSubviews、drawRect与sizeToFi

          本文链接:https://www.haomeiwen.com/subject/fbcnqctx.html