setNeedsLayout与layoutIfNeeded

476 阅读1分钟
关键点
layoutIfNeeded不一定会调用layoutSubviews方法。
setNeedsLayout一定会调用layoutSubviews方法(有延迟,在下一轮runloop结束前)。
如果想在当前runloop中立即刷新,调用顺序应该是
[self setNeedsLayout];
[self layoutIfNeeded];
反之可能会出现布局错误的问题。
#import "ViewController.h"
#import "LGView.h"

@interface ViewController ()

@property (nonatomic,strong) LGView *lgView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self.view addSubview:self.lgView];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self.lgView setNeedsLayout];
    [self.lgView layoutIfNeeded];
}

- (LGView *)lgView {
    if (!_lgView) {
        _lgView = [[LGView alloc] init];
        _lgView.frame = CGRectMake(0, 150, [UIScreen mainScreen].bounds.size.width, 300);
    }
    return _lgView;
}

@end
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface LGView : UIView

@end

NS_ASSUME_NONNULL_END
#import "LGView.h"
#import <Masonry/Masonry.h>

@interface LGView ()

@property (nonatomic,strong) UIImageView *imageView;
@property (nonatomic,assign) NSInteger index;

@end

@implementation LGView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.index = 1;
        [self addSubview:self.imageView];
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    if (self.index % 2 == 0) {
        self.imageView.frame = self.bounds;
        self.index += 1;
    } else {
        self.imageView.frame = CGRectMake(100, 100, 100, 100);
        self.index += 1;
    }
}

- (UIImageView *)imageView {
    if (!_imageView) {
        _imageView = [[UIImageView alloc] init];
        _imageView.contentMode = UIViewContentModeScaleAspectFit;
        _imageView.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.3];
    }
    return _imageView;
}

@end