iOS layoutSubviews调用时机

一、layoutSubviews在以下情况下会被调用:
1、init初始化不会触发layoutSubviews。
2、addSubview会触发layoutSubviews。如果addSubview 如果连续2个 只会执行一次,因为一次的runLoop结束后,如果有需要刷新,执行一次即可。
3、改变一个UIView的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。
4、滚动一个UIScrollView引发UIView的重新布局会触发layoutSubviews。
5、直接调用setNeedsLayout 或者 layoutIfNeeded。

#import "TestView.h"

@implementation TestView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self){
        NSLog(@"initWithFrame:%@" ,NSStringFromCGRect(frame));
    }
    return self;
}

- (void)layoutSubviews
{
    NSLog(@"layoutSubviews %@", self);
    [super layoutSubviews];
}


@end
#import "ViewController.h"
#import "TestView.h"

@interface ViewController ()

@property (strong, nonatomic) UIScrollView *rootScroll;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    [self testCase4];
}


/**
 init初始化不会触发layoutSubviews
 */
- (void)testCase1
{
    /*
     解释:
     
     走了initWithFrame:方法,但是又有frame值为{{0, 0}, {0, 0}},并不需要绘制任何的东西,
     所以不会触发layoutSubviews
     */
    
    TestView *test = [[TestView alloc]init];
    NSLog(@"%@",NSStringFromCGRect(test.frame));
}

/**
 addSubview会触发layoutSubviews
 */
- (void)testCase2
{
    TestView *test = [TestView new];
    [self.view addSubview:test];
}

/**
 改变一个UIView的Frame会触发layoutSubviews
 */
- (void)testCase3
{
    /*
     解释:
     
     第一次调用layoutSubviews是addSubview调用的
     第二次调用layoutSubviews是改变了frame调用的
     */
    TestView *test = [TestView new];
    test.frame = CGRectMake(0, 0, 100, 100);
    [self.view addSubview:test];
    
    test.frame = CGRectMake(0, 0, 200, 200);
}

/**
 滚动一个UIScrollView引发UIView的重新布局会触发layoutSubviews
 */
- (void)testCase4
{
    CGRect rect    = self.view.bounds;
    CGFloat height = rect.size.height;
    CGFloat width  = rect.size.width;
    
    _rootScroll = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    _rootScroll.delegate = self;
    _rootScroll.pagingEnabled = YES;
    _rootScroll.showsVerticalScrollIndicator = YES;

    for (int i = 0; i< 4; i++) {
        TestView *tmp = [[TestView alloc] initWithFrame:CGRectMake(width*i, 0, width, height)];
        tmp.tag = 10000+i;
        if (i%2 == 0) {
            tmp.backgroundColor = [UIColor redColor];
        }
        [_rootScroll addSubview:tmp];
    }
   
    _rootScroll.contentSize   = CGSizeMake(width * 4, 0);
    [self.view addSubview:_rootScroll];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    TestView *view = [self.view viewWithTag:10000];
    CGRect frame = view.frame;
    frame.size.width -= 0.1;
    view.frame = frame;
}


@end

你可能感兴趣的:(iOS layoutSubviews调用时机)